对于跟踪表的UPDATE的触发器,可以引用两个临时表:已删除和已插入。有没有办法在主键上使用INNER JOIN交叉引用这两个w / o?
我试图在没有外键的情况下保持参照完整性(不要问),所以我使用了触发器。我希望UPDATE到表A中的主键反映在"外键"查找表B,当UPDATE影响表A中的多个记录时,会发生这种情况。
我看到的所有UPDATE触发器示例都依赖于连接已插入和已删除的表来跟踪更改;并且他们使用更新的表的ID字段(主键)来设置连接。但是,如果该ID字段(GUID)是记录(或记录集)中已更改的字段,是否有一种跟踪这些更改的好方法,以便我可以在相应的查找表中强制执行这些更改?
答案 0 :(得分:0)
我和@Aaron在一起,没有主键你就被卡住了。如果你有DDL权限来添加一个触发器,你不能在它的时候添加一个自动增量PK列吗?如果你愿意,它甚至不需要是PK。
答案 1 :(得分:0)
我刚才有这个问题(或者更确切地说,类似的问题),我自己,因此复活......
我最终的方法是简单地禁止更新PK字段,因为它会破坏触发器。值得庆幸的是,我没有商业案例支持更新主键列(无论如何都是代理ID),所以我可以逃脱它。
SQL Server提供UPDATE
函数,以便在触发器中使用,以检查此边缘情况:
CREATE TRIGGER your_trigger
ON your_table
INSTEAD OF UPDATE
AS BEGIN
IF UPDATE(pk1) BEGIN
ROLLBACK
DECLARE @proc SYSNAME, @table SYSNAME
SELECT TOP 1
@proc = OBJECT_NAME(@@PROCID)
,@table = OBJECT_NAME(parent_id)
FROM sys.triggers
WHERE object_id = @@PROCID
RAISERROR ('Trigger %s prevents UPDATE of table %s due to locked primary key', 16, -1, @proc, @table) WITH NOWAIT
END
ELSE UPDATE t SET
col1 = i.col1
,col2 = i.col2
,col3 = i.col3
FROM your_table t
INNER JOIN inserted i ON t.pk1 = i.pk1
END
GO
(请注意,上述内容尚未经过测试,可能包含与XACT_STATE
或TRIGGER_NESTLEVEL
相关的各种问题 - 它只是用于演示原则) < / p>
但是,它有点乱,所以我肯定会考虑代码生成,以便在开发过程中处理对表的更改(甚至可以通过CREATE / ALTER表上的DDL触发器完成)。
如果你有一个复合主键,你可以使用IF UPDATE(pk1) OR UPDATE(pk2)...
或者使用COLUMNS_UPDATED
函数进行一些按位工作,它会根据列序数给你一个位掩码(但我不是将在此处介绍 - 请参阅MSDN / BOL)。
另一个(更简单)选项是DENY UPDATE ON your_table(pk) TO public
,但请记住,sysadmins
(可能dbo
)的任何成员都不尊重此。< / p>