SQL SERVER 准行级触发器
ⅰDeleted表和Inserted表
SQL SERVER只有表级和服务器级(相当)的触发器,在很多需要使用行级触发器的场合,很多同事都开始怀念使用Oracle的日子。但是事实上,我认为SQL SERVER这样做有它的理由(或难处),甚至于很多时候我会说,我们不需要精细到以行来触发的操作,因为我们往往要做的是处理哪些数据而不是哪条数据。不过如果您真的很需要,那么SQL SERVER提供了相应的手段足以让您实现类似的功能,并且应有更大的灵活性。
对于SQL SERVER,一个添修删操作对应于确定的触发器只会作用一次,而不管在这个操作中有多少纪录受到了该次操作的影响,因为它是语句级的。但这并不意味着我们需要去遍历比较整个表才可以得知哪些记录发生了改变。在DML触发器开发中,我们可以通过Deleted表和Inserted表得到激活当前触发器的操作中那些受到影响的记录。
对于这两个表,我们可以这样理解。在一个添修删操作过程中,SQL引擎生成了这两个临时表。他把删除掉的数据暂时存储在Deleted表内,把要追加的数据存储在Inserted表内。而对于修改来说,我们把他理解为删除旧记录和加入新记录两个步骤,那么就是说他在两个表内分别存储了目标记录修改前后的数据。
想要检验这种猜测的合理性,我们不妨用下面的例子试试看。
USE
[
myTestDataBase
]
-- 初始化
IF OBJECT_ID ( ' tbStudents ' , ' TABLE ' ) IS NOT NULL
DROP TABLE [ tbStudents ]
GO
IF OBJECT_ID ( ' tbStudentsLog ' , ' TABLE ' ) IS NOT NULL
DROP TABLE [ tbStudentsLog ]
GO
IF OBJECT_ID ( ' TR_StudentNameChanged ' , ' TR ' ) IS NOT NULL
DROP TRIGGER TR_StudentNameChanged
GO
-- 初始化
IF OBJECT_ID ( ' tbStudents ' , ' TABLE ' ) IS NOT NULL
DROP TABLE [ tbStudents ]
GO
IF OBJECT_ID ( ' tbStudentsLog ' , ' TABLE ' ) IS NOT NULL
DROP TABLE [ tbStudentsLog ]
GO
IF OBJECT_ID ( ' TR_StudentNameChanged ' , ' TR ' ) IS NOT NULL
DROP TRIGGER TR_StudentNameChanged
GO