当指定列中的任何更改时,SQL Server 2008更新触发器不起作用

时间:2013-12-10 05:21:34

标签: sql sql-server sql-server-2008

我在sql server 2008中创建了一个下面的触发器,它在我的W_Data表列PLName中发生更改时不会触发。我在A_Ticket中看到了相同的列数。有人可以帮帮我吗?

CREATE TRIGGER dbo.tr_W_Data
    ON dbo.W_Data
    after update
    AS
        declare @date datetime

        select @date = max(Start_Date) from dbo.W_Schedule

        set NOCOUNT ON;

        if update(PLName)

    begin
      update t set
        I_S1_O = (select count(*) from W_Data w where [Priority] = 'S1' and [Type] <> 'R' and [A_Group] <> '1' and [C_Date]< @date and w.[Product_Name] = t.[Product_Name]), 
        I_S1_R = (select count(*) from W_Data w where [Priority] = 'S1' and [Type] <> 'R' and [A_Group] <> '1' and [C_Date]>= @date and w.[Product_Name] = t.[Product_Name]), 
        I_S1_Re = (select count(*) from W_Data w where [Priority] = 'S1' and [Type] <> 'R' and [R_Group] <> '1' and [R_Group] is not NULL and w.[Product_Name] = t.[Product_Name]), 
        .....
      from ATicket t
    end
    go

1 个答案:

答案 0 :(得分:0)

基本上,在触发器中,您应始终引用InsertedDeleted伪表。对于UPDATE语句,Deleted将包含旧值(在更新之前),而Inserted将包含新值。

然后,您应该加入那些伪表,这些伪表告诉您哪些行已根据您自己的数据表更新,以对这些数据表执行某些操作 - 或将审计记录写入另一个表 - 或者其他什么 - 无论您想要做什么

但请注意:触发器将每行触发一次,并在Inserted中包含一行 - 每个语句将触发一次,因此更多通常不包含正在更新的多行数据。

基本上,你的触发器应该是这样的:

CREATE TRIGGER dbo.tr_W_Data
ON dbo.W_Data
AFTER UPDATE
AS
  DECLARE @date DATETIME

  SELECT @date = MAX(Start_Date) FROM dbo.W_Schedule

  UPDATE t
  SET 
     I_S1_O = (select count(*) from dbo.W_Data w where [Priority] = 'S1' and [Type] <> 'R' and [A_Group] <> '1' and [C_Date]< @date and w.[Product_Name] = t.[Product_Name]), 
     I_S1_R = (select count(*) from dbo.W_Data w where [Priority] = 'S1' and [Type] <> 'R' and [A_Group] <> '1' and [C_Date]>= @date and w.[Product_Name] = t.[Product_Name]), 
     I_S1_Re = (select count(*) from dbo.W_Data w where [Priority] = 'S1' and [Type] <> 'R' and [R_Group] <> '1' and [R_Group] is not NULL and w.[Product_Name] = t.[Product_Name]), 
        .....
   FROM dbo.ATicket t
   INNER JOIN Inserted i ON ....(whatever JOIN condition makes sense).....
   INNER JOIN Deleted d ON  ....(whatever JOIN condition makes sense).....
   WHERE
       d.PLName <> i.PLName  -- take those rows where the "PLName" column has been updated