条件更新存储过程始终触发触发器

时间:2010-03-26 18:54:00

标签: sql-server

我有一个说

的存储过程
update table1 set value1 = 1 where value1 = 0 and date < getdate() 

我有一个类似

的触发器
CREATE TRIGGER NAME ON TABLENAME
FOR UPDATE
...
if UPDATE(value1) 
BEGIN
--Some code to figure out that this trigger has been called
-- the value is always null
END

知道为什么即使存储过程没有更新任何值,也会调用此触发器?

2 个答案:

答案 0 :(得分:3)

阅读有关update()的在线书籍,这实际上是一本很好的阅读。 你可以在这里找到它,http://msdn.microsoft.com/en-us/library/ms187326.aspx

回答: 如果列“更新”,Update()将返回true,即使没有行受更新影响。

例如(设置):

If OBJECT_ID('TestTrigger', 'U') is not null drop table TestTrigger
GO
create table TestTrigger(
  ID int identity(1,1)
, Col1 int
, Col2 int
, Trig varchar(1) default 'N' 
)
Insert into TestTrigger(Col1, Col2) values (1,1)
Insert into TestTrigger(Col1, Col2) values (1,2)
GO
IF OBJECT_ID('Testing', 'TR') is not null drop trigger Testing
GO
Create Trigger Testing on TestTrigger
For Update
as
Begin
If Update(Col1)
    begin
        Update TestTrigger Set Trig='Y' where ID=(Select ID from Inserted)
    end
End 

如果我运行Update TestTrigger Set Col1=0 where Col2=1并检查受影响的行,我会看到

(1 row(s) affected)
(1 row(s) affected)

我们知道这是真的,1受更新语句的影响,另一个受触发器的影响。 如果我运行Update TestTrigger Set Col1=0 where Col2=10,我会看到,

(0 row(s) affected)
(0 row(s) affected)

这意味着Update(Col1)返回true(因为否则我们只会返回受影响的单行)。

如果我运行Update TestTrigger Set Col2=0 where Col2=10,我会看到

(0 row(s) affected)

这是因为不再引用Col1。正如@Schar提到的那样检查@@ RowCount也是一个好主意,或者你可以使用像我一样的东西(链接插入)。

克里斯

编辑:并从创建触发器BO文章(http://msdn.microsoft.com/en-us/library/ms189799.aspx),

添加
  

当有效时触发这些触发器   事件被解雇,无论是否   或者不会影响任何表行。

答案 1 :(得分:0)

一位朋友评论说我会对触发器中的以下行很好(指示触发器始终触发)

IF @@ROWCOUNT=0 RETURN