Eu tenho um problema com este gatilho AFTER INSERT que estou usando para auditoria:
Não é possível inserir o valor NULL na coluna 'TermID', tabela 'AuditTerms'; coluna não permite nulos. Falha na INSERÇÃO.
Definição da tabela TermKeys:
TermID int Identity PK
Key int
Action int
Definição da tabela AuditTerms:
TermID int PK
UpdatedAt datetime
Definição de gatilho:
ALTER TRIGGER [dbo].[TRG_TermKeys_AuditTerms_IUD] ON [dbo].[TermKeys]
AFTER INSERT, UPDATE, DELETE NOT FOR REPLICATION AS
BEGIN
SET NOCOUNT ON;
DECLARE @termid int;
IF EXISTS(SELECT * FROM Deleted) SELECT @termid = TermID FROM Deleted;
IF EXISTS(SELECT * FROM Inserted) SELECT @termid = TermID FROM Inserted;
IF EXISTS(SELECT TermID FROM AuditTerms WHERE (TermID = @termid))
BEGIN
UPDATE AuditTerms SET UpdatedAt = getdate() WHERE (TermID = @termid);
END
ELSE
BEGIN
INSERT INTO AuditTerms (TermID, UpdatedAt) VALUES (@termid, getdate());
END;
END;
TermID é um campo de identidade e o PK, a tabela inserida contém o valor de identidade neste ponto?
Devo usar @@Identity ou alguma outra forma?
O erro é causado pela tentativa de inserção
AuditTerms
quando não há chave primária correspondente emTermKeys
. Depois de criar o esquema da tabela e o gatilho no tempdb e inserir alguns registros no TermKeys, consegui reproduzi-lo emitindo um DELETE duas vezes no mesmo TermID:dá-me:
Algo no código do aplicativo pode estar executando a consulta duas vezes; Não consigo ver outra maneira de obter um valor nulo. A melhor maneira de evitar o erro é adicionar uma verificação preventiva de @@ROWCOUNT no início do gatilho, pois ele retornará o número total de linhas afetadas pela instrução DML que o disparou.