Usuário com melhor resposta
TRIGGER e Procedure instrução DML não pode ter gatilhos habilitados se a instrução contém uma cláusula OUTPUT sem cláusula INTO.

Pergunta
-
Boa noite!
Estou com uma situação, tenho uma tabela chamada
alm_entrada_produto_item a qual é inserida pela procedure [prc_ALM_InsertEntradaProdutoItem]
ALTER PROCEDURE [prc_ALM_InsertEntradaProdutoItem]
@p_id_entidade int,
@p_id_entrada_produto_item int,
@p_id_entrada_produto_itemSaida int OUTPUT,
@p_id_produto int,
@p_qtde_produto int,
@p_valor_unitario decimal(10, 2),
@p_data_validade datetime,
@p_numero_lote nvarchar(45),
@p_id_entrada_produto int,
@p_id_almoxarifado int,
@p_observacao_entrada varchar(3000),
@p_tipo_entrada varchar(45),
@p_id_transferencia int,
@p_id_estorno int
AS
BEGIN TRANSACTION
BEGIN try
DECLARE
@contador int
SELECT @contador = count_big(*)
FROM dbo.alm_entrada_produto_item
WHERE (id_entidade=@p_id_entidade) and alm_entrada_produto_item.id_entrada_produto_item = @p_id_entrada_produto_item
IF @contador > 0
UPDATE dbo.alm_entrada_produto_item
SET
id_produto = @p_id_produto,
qtde_produto = @p_qtde_produto,
valor_unitario = @p_valor_unitario,
data_validade = @p_data_validade,
numero_lote = @p_numero_lote,
id_almoxarifado = @p_id_almoxarifado,
observacao_entrada = @p_observacao_entrada,
tipo_entrada = @p_tipo_entrada
WHERE (id_entidade=@p_id_entidade) and alm_entrada_produto_item.id_entrada_produto_item = @p_id_entrada_produto_item
ELSE
BEGIN
INSERT dbo.alm_entrada_produto_item(
id_entidade,
id_produto,
qtde_produto,
valor_unitario,
data_validade,
numero_lote,
id_entrada_produto,
id_almoxarifado,
observacao_entrada,
tipo_entrada,
id_transferencia,
id_estorno)
VALUES (
@p_id_entidade,
@p_id_produto,
@p_qtde_produto,
@p_valor_unitario,
@p_data_validade,
@p_numero_lote,
@p_id_entrada_produto,
@p_id_almoxarifado,
@p_observacao_entrada,
@p_tipo_entrada,
@p_id_transferencia,
@p_id_estorno)
END
COMMIT TRANSACTION -- Efetivando alterações na base
SET @p_id_entrada_produto_itemSaida=SCOPE_IDENTITY()
return @p_id_entrada_produto_itemSaida
END try
BEGIN CATCH
PRINT ERROR_MESSAGE()
ROLLBACK TRANSACTION -- Desfazendo as alterações na base
END CATCH
----------------------------------
e a Tabela alm_entrada_produto_item contém um trigger que atualiza o saldo do estoque na tabela
alter TRIGGER [tr_ObterIDAlmAtualizarSaldoEstoque]
ON [dbo].[alm_entrada_produto_item]
AFTER INSERT AS
DECLARE
@p_id_entidade int
SELECT @p_id_entidade = (select top 1 id_entidade FROM inserted)
IF (@p_id_entidade is null)
begin
RAISERROR ('Informe a entidade antes de prosseguir', 11,1);
Rollback;
end
ELSE
begin
EXECUTE prc_ALM_AtualizarEstoque
SELECT
id_entidade,
id_entrada_produto,
id_produto,
qtde_produto,
id_almoxarifado,
valor_unitario,
data_validade,
numero_lote
FROM INSERTED
END
que por sua vez chama a procedure prc_ALM_AtualizarEstoque para atualizar o saldo
ALTER PROCEDURE prc_ALM_AtualizarEstoque
@p_id_entidade int,
@p_id_entrada_produto int,
@p_id_produto int,
@p_qtde_produto int,
@p_id_almoxarifado int,
@p_valor_unitario decimal(10, 2),
@p_data_validade datetime,
@p_numero_lote nvarchar(45)
AS
BEGIN
DECLARE
@contador int
SELECT @contador = count_big(*)
FROM alm_estoque
WHERE
(id_entidade=@p_id_entidade) AND
id_produto = @p_id_produto AND
id_almoxarifado = @p_id_almoxarifado AND
numero_lote = @p_numero_lote AND
data_validade = @p_data_validade AND
id_entrada_produto = @p_id_entrada_produto
IF @contador > 0
begin
UPDATE alm_estoque
SET
qtde_produto = qtde_produto + @p_qtde_produto,
id_almoxarifado = @p_id_almoxarifado
WHERE (id_entidade=@p_id_entidade) AND
id_produto = @p_id_produto AND
id_almoxarifado = @p_id_almoxarifado AND
numero_lote = @p_numero_lote AND
data_validade = @p_data_validade AND
id_entrada_produto = @p_id_entrada_produto
end
ELSE
begin
INSERT dbo.alm_estoque(
id_entidade,
id_entrada_produto,
id_produto,
qtde_produto,
id_almoxarifado,
valor_unitario,
data_validade,
numero_lote)
VALUES (
@p_id_entidade,
@p_id_entrada_produto,
@p_id_produto,
@p_qtde_produto,
@p_id_almoxarifado,
@p_valor_unitario,
@p_data_validade,
@p_numero_lote)
end
END
Porém quando tento incluir na tabela alm_entrada_produto_item me aparece essa mensagem
A tabela de destino 'alm_entrada_produto_item' da instrução DML não pode ter gatilhos habilitados se a instrução contém uma cláusula OUTPUT sem cláusula INTO.
Já tentei de todas as formas, se alguém puder me ajudar, agradeço.
- Editado Elton07 domingo, 4 de agosto de 2019 22:59 MAIS LEGÍVEL.
Respostas
-
-
Eu tenho uma outra trigger vinculada a tabela entrada_produto_item que basicamente, faz o seguinte, minha chave tá como autoincremento e tenho um campo chamado num_entrada_produto que por essa trigger eu obtenho o valor do último inserido e insiro mais um nesse campo, abaixo o código dela.
ALTER TRIGGER [dbo].[tr_ObterIDAlmEntradaProduto_item]
ON [dbo].[alm_entrada_produto_item]
INSTEAD OF INSERT AS
begin
DECLARE
@p_id_entidade int,
@p_idSequencial int
SET @p_id_entidade = (select TOP 1 id_entidade FROM inserted)
SET @p_idSequencial =(SELECT max(t.num_entrada_produto_item) from alm_entrada_produto_item t inner join inserted on t.id_entidade= inserted.id_entidade and t.id_entrada_produto=inserted.id_entrada_produto)
IF (@p_id_entidade is null)
begin
RAISERROR ('Informe a entidade antes de prosseguir', 11,1);
Rollback;
end
ELSE
begin
if ((@p_idSequencial <= 0) or (@p_idSequencial is null))
begin
set @p_idSequencial = 1
end
else
begin
set @p_idSequencial = @p_idSequencial + 1
end
INSERT alm_entrada_produto_item(
id_entidade
,num_entrada_produto_item
,id_produto
,qtde_produto
,valor_unitario
,data_validade
,numero_lote
,id_entrada_produto
,id_almoxarifado
,observacao_entrada
,tipo_entrada
,id_transferencia
,id_estorno)
OUTPUT INSERTED.id_entrada_produto_item
select
id_entidade
,@p_idSequencial
,id_produto
,qtde_produto
,valor_unitario
,data_validade
,numero_lote
,id_entrada_produto
,id_almoxarifado
,observacao_entrada
,tipo_entrada
,id_transferencia
,id_estorno
from inserted
END
endElton,
Olha no seu código a clausula Output!
Se a coluna é autonumerada no insert da mesma tabela você não precisa passar valores, mas caso deseje via Output direcionar o resultado para outra tabela ou apresentar em tela, neste caso, esta coluna autonumerada poderá ser utilizada.
Seria possível desativar esta Trigger para testarmos?
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
- Marcado como Resposta Elton07 segunda-feira, 5 de agosto de 2019 21:57
-
Elton,
Que bom, fico feliz que tenhamos ajudado.
Em relação ao Sequence na verdade você vai criar um objeto sequenciador de forma geral, a não ser que você pense em criar mais de um sequence, cada um vinculado a sua específica tabela, veja o exemplo abaixo apresentado pela documentação Microsoft:
https://docs.microsoft.com/pt-br/sql/relational-databases/sequence-numbers/sequence-numbers?view=sql-server-2017#a-using-a-sequence-number-in-a-single-table
--Create the Test schema CREATE SCHEMA Test ; GO -- Create a table CREATE TABLE Test.Orders (OrderID int PRIMARY KEY, Name varchar(20) NOT NULL, Qty int NOT NULL); GO -- Create a sequence CREATE SEQUENCE Test.CountBy1 START WITH 1 INCREMENT BY 1 ; GO -- Insert three records INSERT Test.Orders (OrderID, Name, Qty) VALUES (NEXT VALUE FOR Test.CountBy1, 'Tire', 2) ; INSERT test.Orders (OrderID, Name, Qty) VALUES (NEXT VALUE FOR Test.CountBy1, 'Seat', 1) ; INSERT test.Orders (OrderID, Name, Qty) VALUES (NEXT VALUE FOR Test.CountBy1, 'Brake', 1) ; GO -- View the table SELECT * FROM Test.Orders ; GO
Demais links úteis:
CREATE SEQUENCE (Transact-SQL)
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
- Marcado como Resposta Elton07 terça-feira, 6 de agosto de 2019 14:16
-
-
Eu vou estudar mais o Sequence e como vou poder implementar, realmente eu vejo que além de mais performático é mais prático do que o método que eu estou usando hoje.
Agora tudo ficou mais fácil KKK.
Elton,
Ok, espero que você consiga, depois retorne nos informando se deu tudo certo.
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
- Marcado como Resposta Elton07 terça-feira, 31 de dezembro de 2019 14:43
Todas as Respostas
-
-
-
Elton,
Aparentemente a ordem de execução definida para todo este processo é esta:
- alm_entrada_produto_item a qual é inserida pela procedure [prc_ALM_InsertEntradaProdutoItem];
- alm_entrada_produto_item também possui um Trigger, que atualiza o saldo do estado na mesma tabela; e
- Alm_entrada_produto_item e depois chama a prc_ALM_AtualizarEstoque atualiza o Saldo da tabela ALM_Estoque.
É isso mesmo?
Parece-me que existe uma redundância na execução! Por gentileza, você poderia desativar inicialmente a trigger?
Além das sugestões apresentadas anteriormente sobre o uso de Trigger, gostaria de destacar também, caso queria saber mais sobre como construir Triggers que levam em consideração a análise e abordagem do processamento de multiplas linhas, além do link apresentado anteriormente, recomendo caso necessário o acesso ao link da documentação oficial da Microsoft Brasil: Crie gatilhos DML para tratar várias linhas de dados.
Além disso, toda documentação oficial Microsoft no que se refere ao SQL Server e Azure esta sendo construída, escrita, reescrita e mantida por nós MVPs de Data Platform localizados em diversos países do mundo, algo que não representa ser 100% correto ou infalível, estamos em constante melhorias e correções.
Outro link muito útil e que lhe poderá ajudar, relaciona-se ao próprio conceito de Gatilhos DML.
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
Bom dia José!
Testei a instrução que você me sugeriu e alterei a trigger para ficar como dito, porém o mesmo erro é informado, estou tentando inserir pela procedure
EXECUTE [prc_ALM_InsertEntradaProdutoItem]
1,0,0,5,100,'0.90',null,null,54,23,null,'e',null,nullAbaixo o retorno, quando eu desabilito a trigger [tr_ObterIDAlmAtualizarSaldoEstoque] o insert acima funciona.
(0 linha(s) afetadas)
A tabela de destino 'alm_entrada_produto_item' da instrução DML não pode ter gatilhos habilitados se a instrução contém uma cláusula OUTPUT sem cláusula INTO.
Obrigado pela ajuda , fico no aguardo da resposta.
-
-
Bom dia Junior!
A lógica criada é a seguinte, eu faço a inclusão chamando a procedure [prc_ALM_InsertEntradaProdutoItem] ao inserir na tabela EntradaProdutoItem disparo a trigger que verifica o que foi incluído e atualiza os quantitativos e valores de outra tabela chamada estoque através da procedure prc_ALM_AtualizarEstoque.
Ordem
1 - Procedure [prc_ALM_InsertEntradaProdutoItem]
2 - Após Inclusão chamo a Trigger [tr_ObterIDAlmAtualizarSaldoEstoque] que dentro dela executa uma outra procedure chamada [prc_ALM_AtualizarEstoque].
-
Elton,
Ok, obrigado pelo esclarecimento, vamos por partes então:
- Se você desativou o Trigger tr_ObterIDAlmAtualizarSaldoEstoque o insert acontece, então o problema esta justamente na passado dos dados dentro da sua Stored Procedure: prc_ALM_InsertEntradaProdutoItem
Existe a possibilidade de fazermos um teste, remover a chamada da Stored Procedure dentro da trigger e verifique se algum erro é apresentado.
Verifique os blocos de comando Insert que você esta utilizando tanto no trigger, como principalmente em suas stored procedures.
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
-
Eu comentei a chamada da Procedure dentro da trigger
ALTER TRIGGER [dbo].[tr_ObterIDAlmAtualizarSaldoEstoque]
ON [dbo].[alm_entrada_produto_item]
AFTER INSERT AS
-- chama procedimento de atualização de estoque
declare @p_id_entidade int,
@p_id_entrada_produto int,
@p_id_produto int,
@p_qtde_produto int,
@p_id_almoxarifado int,
@p_valor_unitario decimal(10,2),
@p_data_validade datetime,
@p_numero_lote nvarchar(45);
SELECT @p_id_entidade= id_entidade,
@p_id_entrada_produto= id_entrada_produto,
@p_id_produto= id_produto,
@p_qtde_produto= qtde_produto,
@p_id_almoxarifado= id_almoxarifado,
@p_valor_unitario= valor_unitario,
@p_data_validade= data_validade,
@p_numero_lote= numero_lote
from INSERTED;
IF (@p_id_entidade is null)
begin
RAISERROR ('Informe a entidade antes de prosseguir', 11,1);
Rollback;
end
ELSE
begin
PRINT 'OK'
--EXECUTE prc_ALM_AtualizarEstoque
-- @p_id_entidade, @p_id_entrada_produto, @p_id_produto,@p_qtde_produto, @p_id_almoxarifado, @p_valor_unitario,@p_data_validade, @p_numero_lote;
ENDPorém o erro ainda persiste.
-
Elton,
Então, já identificamos que o erro não esta no [tr_ObterIDAlmAtualizarSaldoEstoque] e na Stored Procedure prc_ALM_AtualizarEstoque.
Você tem certeza que não existe nenhum outro trigger?
Temos agora que verificar o código da outra Stored Procedure prc_ALM_InsertEntradaProdutoItem.
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
Eu tenho uma outra trigger vinculada a tabela entrada_produto_item que basicamente, faz o seguinte, minha chave tá como autoincremento e tenho um campo chamado num_entrada_produto que por essa trigger eu obtenho o valor do último inserido e insiro mais um nesse campo, abaixo o código dela.
ALTER TRIGGER [dbo].[tr_ObterIDAlmEntradaProduto_item]
ON [dbo].[alm_entrada_produto_item]
INSTEAD OF INSERT AS
begin
DECLARE
@p_id_entidade int,
@p_idSequencial int
SET @p_id_entidade = (select TOP 1 id_entidade FROM inserted)
SET @p_idSequencial =(SELECT max(t.num_entrada_produto_item) from alm_entrada_produto_item t inner join inserted on t.id_entidade= inserted.id_entidade and t.id_entrada_produto=inserted.id_entrada_produto)
IF (@p_id_entidade is null)
begin
RAISERROR ('Informe a entidade antes de prosseguir', 11,1);
Rollback;
end
ELSE
begin
if ((@p_idSequencial <= 0) or (@p_idSequencial is null))
begin
set @p_idSequencial = 1
end
else
begin
set @p_idSequencial = @p_idSequencial + 1
end
INSERT alm_entrada_produto_item(
id_entidade
,num_entrada_produto_item
,id_produto
,qtde_produto
,valor_unitario
,data_validade
,numero_lote
,id_entrada_produto
,id_almoxarifado
,observacao_entrada
,tipo_entrada
,id_transferencia
,id_estorno)
OUTPUT INSERTED.id_entrada_produto_item
select
id_entidade
,@p_idSequencial
,id_produto
,qtde_produto
,valor_unitario
,data_validade
,numero_lote
,id_entrada_produto
,id_almoxarifado
,observacao_entrada
,tipo_entrada
,id_transferencia
,id_estorno
from inserted
END
end -
Eu tenho uma outra trigger vinculada a tabela entrada_produto_item que basicamente, faz o seguinte, minha chave tá como autoincremento e tenho um campo chamado num_entrada_produto que por essa trigger eu obtenho o valor do último inserido e insiro mais um nesse campo, abaixo o código dela.
ALTER TRIGGER [dbo].[tr_ObterIDAlmEntradaProduto_item]
ON [dbo].[alm_entrada_produto_item]
INSTEAD OF INSERT AS
begin
DECLARE
@p_id_entidade int,
@p_idSequencial int
SET @p_id_entidade = (select TOP 1 id_entidade FROM inserted)
SET @p_idSequencial =(SELECT max(t.num_entrada_produto_item) from alm_entrada_produto_item t inner join inserted on t.id_entidade= inserted.id_entidade and t.id_entrada_produto=inserted.id_entrada_produto)
IF (@p_id_entidade is null)
begin
RAISERROR ('Informe a entidade antes de prosseguir', 11,1);
Rollback;
end
ELSE
begin
if ((@p_idSequencial <= 0) or (@p_idSequencial is null))
begin
set @p_idSequencial = 1
end
else
begin
set @p_idSequencial = @p_idSequencial + 1
end
INSERT alm_entrada_produto_item(
id_entidade
,num_entrada_produto_item
,id_produto
,qtde_produto
,valor_unitario
,data_validade
,numero_lote
,id_entrada_produto
,id_almoxarifado
,observacao_entrada
,tipo_entrada
,id_transferencia
,id_estorno)
OUTPUT INSERTED.id_entrada_produto_item
select
id_entidade
,@p_idSequencial
,id_produto
,qtde_produto
,valor_unitario
,data_validade
,numero_lote
,id_entrada_produto
,id_almoxarifado
,observacao_entrada
,tipo_entrada
,id_transferencia
,id_estorno
from inserted
END
endElton,
Olha no seu código a clausula Output!
Se a coluna é autonumerada no insert da mesma tabela você não precisa passar valores, mas caso deseje via Output direcionar o resultado para outra tabela ou apresentar em tela, neste caso, esta coluna autonumerada poderá ser utilizada.
Seria possível desativar esta Trigger para testarmos?
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
- Marcado como Resposta Elton07 segunda-feira, 5 de agosto de 2019 21:57
-
-
Elton,
Outra observação que gostaria de expor, em relação ao Count_Big(), se o seu tipo de dados é Int, então utilize somente a função Count(), o count_big é utilizado quando o tipo de dados que armazena o valor for BigInt.
Isso é evidenciado na documentação da Microsoft.
BEGIN TRANSACTION
BEGIN try
DECLARE
@contador int
SELECT @contador = count_big(*)
FROM dbo.alm_entrada_produto_item
WHERE (id_entidade=@p_id_entidade) and alm_entrada_produto_item.id_entrada_produto_item = @p_id_entrada_produto_itemPedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
O banco que eu estava utilizando era o Mysql, ao por questão de praticidade acabei por optando converter toda a estrutura para o SQL Server, utilizei a ferramenta Microsoft SQL Server Migration Assistant for MySQL ai em alguns casos ele converteu int em count(*) em count_big(*) mas irei ajustar isso também, obrigado pelo feedback.
-
Junior, fiz o seguinte teste, fiz um DROP na trigger [tr_ObterIDAlmEntradaProduto_item] e tentei fazer a inclusão EXECUTE [prc_ALM_InsertEntradaProdutoItem]
1,0,0,5,100,'0.90',null,null,54,23,null,'e',null,nullE a inserção foi feita corretamente, agora quando tento criar novamente a trigger [tr_ObterIDAlmEntradaProduto_item] é informada a mensagem:
Mensagem 334, Nível 16, Estado 1, Procedimento tr_ObterIDAlmEntradaProduto_item, Linha 39
A tabela de destino 'alm_entrada_produto_item' da instrução DML não pode ter gatilhos habilitados se a instrução contém uma cláusula OUTPUT sem cláusula INTO. -
-
Elton,
Tem mais alguma coisa confusa nesta estrutura, se você apagou a trigger, como pode ele estar sendo chamado novamente.
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
Junior eu fiz o seguinte fiz uns ajustes na trigger tr_ObterIDAlmEntradaProduto_item, e retirei a cláusula OUTPUT INSERTED.id_entrada_produto_item do insert funcionou.
Código Anterior:
INSERT alm_entrada_produto_item(
id_entidade
,num_entrada_produto_item
,id_produto
,qtde_produto
......
,id_estorno)
OUTPUT INSERTED.id_entrada_produto_item
select
id_entidade
,@p_idSequencial
,id_produto
,qtde_produto
....
,id_estorno
from inserted
ENDCódigo Novo:
INSERT INTO alm_entrada_produto_item(
id_entidade
,num_entrada_produto_item
,id_produto
,qtde_produto
...
,id_estorno)
select
@p_id_entidade
,@p_idSequencial
,@p_id_produto
,@p_qtde_produto
....
,@p_id_estorno
ENDAi possibilitou a criação dela novamente, porém eu não consigo obter o valor do campo autoincremento do ID da tabela.
-
-
José qual seria a melhor indicação no caso?
No seguinte cenário:
Tabela Empresa /Entidade - Chave Id_entidade
Tabela Entrada_Produto - Chave Id_entrada_produto e além da chave tenho um campo Num_entrada_produto que é incrementado de acordo com a entidade. Exemplo:
Tabela Entrada
Id_entrada_produto | ID_entidade | num_entrada_produto
1 1 1
2 1 2
3 2 1
4 1 3
-
Elton,
Obrigado pelo retorno, que bom que esta primeiro passo conseguimos identificar a causa.
Pois bem, em relação ao Identity(), ele é bom e ao mesmo tempo ruim (kkkk), tudo vai depender da maneira e forma de implementação.
Quando utilizamos este recurso o SQL Server nos oferece algumas funcionalidades que podem ser utilizadas em conjunto, dentro elas a mais conhecida que é a variável @@Identity, temos outras:
Neste link você vai poder encontrar um exemplo de código que compara e apresenta as diferenças entre estas três funcionalidades:
https://www.codeproject.com/Articles/103610/Difference-between-IDENTITY-SCOPE-IDENTITY-IDENT-C
Se eu entendi, você tem a necessidade de obter o número do Identity para se reutilizado posteriormente, já pensou em utilizar um outro Trigger mas do tipo Instead Of:
-- Criando a Tabela -- Create Table TesteIdentity (Codigo Int Identity(1,1), Descricao Varchar(30) Not Null) Go -- Criando a Trigger do tipo Instead Of Insert -- Create Trigger T_ObterValorIdentity On TesteIdentity Instead Of Insert AS BEGIN Set NoCount On DECLARE @Relacao TABLE (Codigo INT); INSERT TesteIdentity (Descricao) Output inserted.Codigo Into @Relacao SELECT Descricao FROM inserted Select * From @Relacao End Go -- Inserindo -- Insert Into TesteIdentity Values ('Pedro'), ('Antonio'),('Galvão'),('Junior') Go -- Validando -- Select * From TesteIdentity Go
Ou então arriscar fazendo uso de algumas das funcionalidades que eu citei anteriormente.
Referências:
http://www.sqlservertutorial.net/sql-server-triggers/sql-server-instead-of-trigger/
https://www.tutorialgateway.org/instead-of-insert-triggers-in-sql-server/
https://docs.microsoft.com/pt-br/sql/t-sql/statements/create-trigger-transact-sql?view=sql-server-2017
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
José muito obrigado!
Irei ler com calma esse conteúdo que você passou agora para tentar implementar. Já favoreitei o site https://portosql.wordpress.com/contato/ vi que tem ótimos posts que poderão me ajudar ao longo desse redescobrimento de banco de dados.
Muito provavelmente ainda irei buscar o conhecimento dessa fonte que é a sua Experiência rs. Valeu!
-
KKKk, É meu velho, primeira etapa concluída com sucesso. Obrigado novamente!
Em relação a trigger a ALTER TRIGGER [dbo].[tr_ObterIDAlmEntradaProduto_item]
ON [dbo].[alm_entrada_produto_item]
INSTEAD OF INSERT AS já fazia isso, ela antes de inserir olhava qual era a última numeração do campo num_entrada e adicionava mais um. Pelo visto terei que desativar ela realmente.Vou olhar também o conteúd que você indicou.
Obrigado novamente pela atenção e por compartilhar a sua experiência. Com certeza terei mais dúvidas kkkk
-
Elton,
Ok, ficamos no aguardo, se for o caso pense na possibilidade de utilizar as outras técnicas destacadas, mas isso vai depender da sua necessidade.
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
Junior,
Estou pensando na possibilidade do SEQUENCE, porém pelo que eu andei lendo eu não tenho como sequenciar por um campo específico, no meu caso por empresa, ou seja cada empresa ter o seu próprio sequence.
Quanto a situação acima consegui resolver agora a noite, analisei cuidadosamente e seguir todas as dicas para colocar nas procedures e nas triggers e funcionou junto com a minha aplicação.
Muito obrigado novamente!
-
Elton,
Que bom, fico feliz que tenhamos ajudado.
Em relação ao Sequence na verdade você vai criar um objeto sequenciador de forma geral, a não ser que você pense em criar mais de um sequence, cada um vinculado a sua específica tabela, veja o exemplo abaixo apresentado pela documentação Microsoft:
https://docs.microsoft.com/pt-br/sql/relational-databases/sequence-numbers/sequence-numbers?view=sql-server-2017#a-using-a-sequence-number-in-a-single-table
--Create the Test schema CREATE SCHEMA Test ; GO -- Create a table CREATE TABLE Test.Orders (OrderID int PRIMARY KEY, Name varchar(20) NOT NULL, Qty int NOT NULL); GO -- Create a sequence CREATE SEQUENCE Test.CountBy1 START WITH 1 INCREMENT BY 1 ; GO -- Insert three records INSERT Test.Orders (OrderID, Name, Qty) VALUES (NEXT VALUE FOR Test.CountBy1, 'Tire', 2) ; INSERT test.Orders (OrderID, Name, Qty) VALUES (NEXT VALUE FOR Test.CountBy1, 'Seat', 1) ; INSERT test.Orders (OrderID, Name, Qty) VALUES (NEXT VALUE FOR Test.CountBy1, 'Brake', 1) ; GO -- View the table SELECT * FROM Test.Orders ; GO
Demais links úteis:
CREATE SEQUENCE (Transact-SQL)
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
- Marcado como Resposta Elton07 terça-feira, 6 de agosto de 2019 14:16
-
-
-
-
Eu vou estudar mais o Sequence e como vou poder implementar, realmente eu vejo que além de mais performático é mais prático do que o método que eu estou usando hoje.
Agora tudo ficou mais fácil KKK.
Elton,
Ok, espero que você consiga, depois retorne nos informando se deu tudo certo.
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
- Marcado como Resposta Elton07 terça-feira, 31 de dezembro de 2019 14:43
-
-
Bom dia!
Apenas retornando, deu tudo certo sim,
Obrigado a todos.
Abraço,
Elton007,
Obrigado pelo retorno.
Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]