2013-12-12 75 views
0

我在触发插入Table1后会触发Table2更新后Table1中的TableA会在Table2中更新Status_Column其中Table1.id = table2.id,删除table1后会删除table2中的行where table1 .ID = table2.id。我的触发器不起作用

create TRIGGER mytrigger 
     ON Table1 
     after UPDATE,INSERT,DELETE 
    AS 
    Begin 
     if update (columnA) 
      BEGIN 
      SET NOCOUNT ON; 
       declare @ID int 
       select @ID = ID from DELETED  
       UPDATE Table2 
       SET T2.Status_Column ='Updated' 
       From Table2 T2 
       inner join Table1 T1 on T1.ID = T2.ID 
       where T1.ID = @ID 
      End 
     else if exists (select * from inserted) 
      Begin 
      declare @table2_ID int 
      select @table2_ID = ID from inserted  
       insert into table2 (ID,Status_Column) values (@table2_ID,'New') 
      End 
     else if exists (select ID from deleted) 
      Begin 
       delete from table2 
       from table2 T2 , Deleted d 
       where t2.id= d.id 
      End 
    End 

只有delete语句工作:(

+0

'inserted'和'deleted'是表格,以便它们可以表示设置操作的结果。假设它们总是包含一行,设计一个触发器通常是一个糟糕的计划。如果你完全确定永远不会有多行,那么请添加一个行数检查并使用'RaIsError'来明确告知那些稍后来到的人他们试图执行不可接受的语句。 ('如果从插入(SELECT COUNT(*))> 1个RAISERROR( 'FooTable_Insert:没有多行可被处理',25,42)与log') – HABO

+0

的UPDATE()函数两者INSERT返回true,并且更新操作,所以你的逻辑需要一点工作。 – HABO

+0

@HABO你对这个触发器的修改建议是什么? – Interaoi

回答

0

你根本缺陷是,你似乎期望触发每行被解雇一次 - 这是在SQL Server的情况相反。 ,触发器触发每条语句一次,假表Deleted可能包含多行

鉴于该选项卡le可能包含多行 - 你期望哪一个会在这里被选中?

select @ID = ID from DELETED   

这是未定义的 - 您可能会从Deleted中的任意行获取值。

您需要用知识Deleted包含多行重写您的整个触发器!您需要使用基于集合的操作 - 不要指望Deleted中只有一行!

+0

如果存在(select * from inserted)到if(select * from inserted),那么我改变了else else,并且每件事情都有效,但是如果我更新触发器更新并且插入在同一时间..什么会改变也工作? – Interaoi