Tenho a consulta abaixo, que atualiza o carimbo de data/hora para 10 registros.
UPDATE [dbo].[file] SET timestamp = GETDATE() WHERE id <= 10
Criei um gatilho nessa tabela Inserir/Atualizar.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[trg_file]
ON [dbo].[file]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ID BIGINT;
DECLARE @RES VARCHAR(100);
SET @ID = (select id from INSERTED);
SET @RES = (select timestamp from INSERTED);
IF @RES IS NOT NULL
DELETE FROM [dbo].[file] WHERE id IN (@ID)
END
Dá erro
Msg 512, Level 16, State 1, Procedure trg_file
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated.
Parece que o problema está aqui, pois está recebendo vários registros ao mesmo tempo.
SET @ID = (select id from INSERTED);
Como resolver isso? Via Cursor vi um pouco do post.
Quero aplicar meu gatilho na atualização de vários valores.
Qual é a melhor solução para isso?
Você precisa ter certeza de que tudo o que está fazendo no gatilho pode lidar com várias linhas. Você pode limitar o valor @ID a apenas um único valor modificado, como sugere Akina, mas provavelmente não é isso que você deseja.
Você não tem nenhuma lógica real dentro do gatilho de exemplo enviado, então incluí aqui um exemplo do que poderia ser feito usando a tabela INSERTED, permitindo uma modificação de várias linhas.
Para copiar a lógica que você estabeleceu acima, este exemplo mostra uma maneira de fazer isso.
Quando você está dentro de uma trigger, você tem acesso a duas tabelas virtuais. INSERIDO e EXCLUÍDO. Eles têm as mesmas colunas da tabela base. A tabela INSERTED possui os valores do NEW (e se estiver em uma trigger AFTER, é equivalente aos valores CURRENT). A tabela DELETED contém as linhas PRIOR e DELETED.
Se existir uma linha na tabela DELETED, mas não estiver na tabela INSERTED, a linha foi excluída. Você pode comparar os valores das tabelas DELETED e INSERTED para ver os valores alterados (certifique-se de considerar NULL).
No entanto, você precisa ter cuidado aqui, a tabela INSERTED contém todos os valores, mesmo que o carimbo de data e hora não esteja mudando, então você precisa fazer um pouco mais de lógica para ter certeza de excluir apenas quando o valor do carimbo de data e hora realmente mudar.
Esta é uma das melhores maneiras (na minha experiência) de conseguir isso.
Isso detectará qualquer alteração no valor do carimbo de data/hora. Isso permitirá que o valor do carimbo de data/hora seja definido quando a linha for criada pela primeira vez, porém, NÃO permitirá que o valor seja alterado depois disso (mesmo que seja criado com um valor NULL).