Inquiridor
É possivel fazer um loop em uma trigger? - "Subquery returned more than 1 value..."

Pergunta
-
Olá, possuo a trigger abaixo com dois UPDATES, e quando dou um INSERT ou UPDATE no meu código, caso haja mais de um registro, dá o famoso erro "Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression."
Gostaria de saber se há como recuperar o valor de cada registro na variavel @DEC_ESTOQUE_OLD e @DEC_ESTOQUE_NEW podendo assim executar o código para cada registro inserido/atualizado.
Trigger:
CREATE TRIGGER Status_Produtos_Empresa_Alteracao ON dbo.TBL_PRODUTOS_EMPRESA
FOR UPDATE AS
DECLARE @INT_CODPROD INT
DECLARE @INT_CODEMPRESA INT
DECLARE @DEC_ESTOQUE_OLD DECIMAL ( 9,3 )
DECLARE @DEC_ESTOQUE_NEW DECIMAL ( 9,3 )SET @INT_CODPROD = (SELECT CODPROD FROM DELETED)
SET @INT_CODEMPRESA = (SELECT CODEMPRESA FROM DELETED)SET @DEC_ESTOQUE_OLD = (SELECT ESTOQUE FROM DELETED)
SET @DEC_ESTOQUE_NEW = (SELECT ESTOQUE FROM INSERTED)BEGIN
IF @DEC_ESTOQUE_OLD <> @DEC_ESTOQUE_NEW
BEGIN
UPDATE TBL_PRODUTOS_EMPRESA SET ESTOQUEDISP = @DEC_ESTOQUE_NEW WHERE CODPROD = @INT_CODPROD AND CODEMPRESA = @INT_CODEMPRESA
UPDATE TBL_GRADES SET ESTOQUEDISP = @DEC_ESTOQUE_NEW WHERE CODPROD = @INT_CODPROD AND CODEMPRESA = @INT_CODEMPRESA
END
ENDCódigo que dispara a trigger (e dá pau)...
UPDATE Tbl_Produtos_Empresa SET PrMedio = 0., PrCusto = 0., Estoque = 0. WHERE CodEmpresa = 1
Todas as Respostas
-
Boa tarde Jonatas é possível sim, dá uma olhada no exemplo:
CREATE TRIGGER Status_Produtos_Empresa_Alteracao ON dbo.TBL_PRODUTOS_EMPRESA
FOR UPDATE AS
DECLARE @INT_CODPROD INT
DECLARE @INT_CODEMPRESA INT
DECLARE @DEC_ESTOQUE_OLD DECIMAL ( 9,3 )
DECLARE @DEC_ESTOQUE_NEW DECIMAL ( 9,3 )DECLARE @INT_CONTADOR_INI INT
DECLARE @INT_CONTADOR_FIM INT
SET @INT_CODPROD = (SELECT CODPROD FROM DELETED)
SET @INT_CODEMPRESA = (SELECT CODEMPRESA FROM DELETED)SET @DEC_ESTOQUE_OLD = (SELECT ESTOQUE FROM DELETED)
SET @DEC_ESTOQUE_NEW = (SELECT ESTOQUE FROM INSERTED)SELECT @INT_CONTADOR_INI = 1
SELECT @INT_CONTADOR_FIM = COUNT(*) FROM DELETED -- NO SEU CASO VERIFICA SE É A INSERT OU A DELETED QUE VC VAI USAR
WHILE @INT_CONTADOR_INI <= @INT_CONTADOR_FIM
BEGIN
IF @DEC_ESTOQUE_OLD <> @DEC_ESTOQUE_NEW
BEGIN
UPDATE TBL_PRODUTOS_EMPRESA SET ESTOQUEDISP = @DEC_ESTOQUE_NEW WHERE CODPROD = @INT_CODPROD AND CODEMPRESA = @INT_CODEMPRESA
UPDATE TBL_GRADES SET ESTOQUEDISP = @DEC_ESTOQUE_NEW WHERE CODPROD = @INT_CODPROD AND CODEMPRESA = @INT_CODEMPRESA
ENDSELECT @INT_CONTADOR_INI = @INT_CONTADOR_INI + 1
ENDEspero ter ajudado
-
Anderson,
Fiz como você me indicou, mas continuou dando o mesmo erro:
CREATE TRIGGER Status_Produtos_Empresa_Alteracao ON dbo.TBL_PRODUTOS_EMPRESA
FOR UPDATE AS
DECLARE @INT_CODPROD INT
DECLARE @INT_CODEMPRESA INT
DECLARE @DEC_ESTOQUE_OLD DECIMAL ( 9,3 )
DECLARE @DEC_ESTOQUE_NEW DECIMAL ( 9,3 )DECLARE @INT_CONTADOR_INI INT
DECLARE @INT_CONTADOR_FIM INTSET @INT_CODPROD = (SELECT CODPROD FROM DELETED)
SET @INT_CODEMPRESA = (SELECT CODEMPRESA FROM DELETED)
SET @DEC_ESTOQUE_OLD = (SELECT ESTOQUE FROM DELETED)
SET @DEC_ESTOQUE_NEW = (SELECT ESTOQUE FROM INSERTED)SET @INT_CONTADOR_INI = 1
SET @INT_CONTADOR_FIM = (SELECT COUNT(*) FROM INSERTED)WHILE @INT_CONTADOR_INI <= @INT_CONTADOR_FIM
BEGINIF @DEC_ESTOQUE_OLD <> @DEC_ESTOQUE_NEW
BEGINUPDATE TBL_PRODUTOS_EMPRESA SET ESTOQUEDISP = @DEC_ESTOQUE_NEW WHERE CODPROD = @INT_CODPROD AND CODEMPRESA = @INT_CODEMPRESA
UPDATE TBL_GRADES SET ESTOQUEDISP = @DEC_ESTOQUE_NEW WHERE CODPROD = @INT_CODPROD AND CODEMPRESA = @INT_CODEMPRESA
ENDSELECT @INT_CONTADOR_INI = @INT_CONTADOR_INI + 1
ENDEu fiz algo errado?
-
Jônatas,
Este erro esta indicando que uma subquery que esta sendo executada esta retornando mais de uma linha, e desta forma, o SQL Server não consegui atualizar valores que estão sendo retornados como dados para fazer a transação ser processada.
Qual é a número da linha que esta sendo retornada com o erro?
-
Olá Jonatas,
Provavelmente o erro está ocorrendo nestas linhas:
SET @INT_CODPROD = (SELECT CODPROD FROM DELETED)
SET @INT_CODEMPRESA = (SELECT CODEMPRESA FROM DELETED)SET @DEC_ESTOQUE_OLD = (SELECT ESTOQUE FROM DELETED)
SET @DEC_ESTOQUE_NEW = (SELECT ESTOQUE FROM INSERTED)Verifique se não está retornando mais de um CODPROD.
Qualquer coisa retorne.
Espero ter ajudado.