我用于审计的这个 AFTER INSERT 触发器有问题:
无法将值 NULL 插入到列“TermID”、表“AuditTerms”中;列不允许空值。插入失败。
TermKeys 表定义:
TermID int Identity PK
Key int
Action int
AuditTerms 表定义:
TermID int PK
UpdatedAt datetime
触发器定义:
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 是一个 Identity 字段和 PK,此时 Inserted 表是否包含 Identity 值?
我应该使用@@Identity 还是其他方式?
AuditTerms
该错误是由于在 中没有对应的主键时尝试插入导致的TermKeys
。在 tempdb 中创建表模式和触发器并在 TermKeys 中插入一些记录后,我能够通过在同一个 TermID 上发出两次 DELETE 来重现它:给我:
应用程序代码中的某些内容可能会运行两次查询;我看不到任何其他获取空值的方法。避免该错误的最佳方法是在触发器的开头添加@@ROWCOUNT 的预防性检查,因为它将返回受触发它的 DML 语句影响的总行数。