2016-10-17 193 views
1

美好的一天我有一个外部的程序存储SQL中的信息,我试图做一个触发器,当表中的某些字段发生更改时更新表。SQL触发器更新

因此,我有一列Contractual Amount应该每更新一次ufAPCHANG1EAMNT,ufAPHANGE2AMNT和的任何值更改。

一个人可以更改这些值中的一个或全部,并且可以是+ ve或-ve,如果它们是对这些字段的任何更改,则应该相应地更新Contractual Amount,但添加+ ve金额并减去负值。

请你可以检查我的代码,让我知道我哪里出错了。

ALTER trigger [dbo].[trgContractualAmt] 
ON [dbo].[Vendor] 
AFTER UPDATE 
AS 
    declare 
     @IdI integer, 
     @value1 decimal, 
     @Value2 decimal, 
     @value3 decimal, 
     @sum decimal, 
     @total decimal 

    SELECT 
     @IdI = i.DCLink, 
     @value1 = i.ufAPCHANGE1AMT, 
     @Value2 = i.ufAPCHANGE2AMNT, 
     @value3 =i.ufAPCHANGE3AMNT, 
     @total = i.ufAPContAmt 
    FROM 
     inserted i 
BEGIN 
    IF TRIGGER_NESTLEVEL() > 1 
     RETURN 

    IF @value1 <> (select ufAPCHANGE1AMT from Vendor where DCLink = @IdI) 
      UPDATE Vendor 
      SET ufAPContAmt = ufAPContAmt + @value1 
      where DCLink = @IdI 

     if @Value2 <> (select ufAPCHANGE2AMNT from Vendor where DCLink = @IdI) 
      UPDATE Vendor 
      SET ufAPContAmt = ufAPContAmt + @value2 
      where DCLink = @IdI 

     if @Value3 <> (select ufAPCHANGE3AMNT from Vendor where DCLink = @IdI) 
      UPDATE Vendor 
      SET ufAPContAmt = ufAPContAmt + @value3 
      where DCLink = @IdI   
END 
+3

你的触发器有** **主要中的缺陷,你似乎认为它会被称为**每排一次* * - 事实并非如此。触发器将在每个语句**中触发一次**,所以如果你的UPDATE语句影响了25行,你将触发**触发**一次,但是,然后“插入”和“删除”将分别包含25行。您的代码在这25行中选择哪一个? 'SELECT ..... FROM Inserted' - 这是非确定性的。你需要重写你的触发器来考虑这个问题! –

+0

谢谢@marc_s,但如果您检查这是更新该特定行时,我插入只有一行。 –

+0

标记您正在使用的dbms。该代码看起来不像ANSI SQL。 – jarlh

回答

1

我会建议在可能时使用简单的查询:

ALTER TRIGGER dbo.trgContractualAmt ON dbo.Vendor 
    AFTER UPDATE 
AS 
    BEGIN 
     UPDATE 
      V 
     SET 
      ufAPContAmt += CASE WHEN (V.ufAPCHANGE1AMT <> I.ufAPCHANGE1AMT) 
           THEN I.ufAPCHANGE1AMT 
           ELSE 0 
          END 
      + CASE WHEN (V.ufAPCHANGE2AMNT <> I.ufAPCHANGE2AMNT) 
        THEN I.ufAPCHANGE2AMNT 
        ELSE 0 
       END 
      + CASE WHEN (V.ufAPCHANGE3AMNT <> I.ufAPCHANGE3AMNT) 
        THEN I.ufAPCHANGE3AMNT 
        ELSE 0 
       END 
     FROM 
      Vendor V 
     INNER JOIN inserted I 
      ON V.DCLink = I.DCLink; 

    END; 
+0

您是否真的需要Where条件,请检查 –

+0

对不起这是Gerald的代码剩下的。我编辑了我的答案,删除。 谢谢 – Kilren

+0

谢谢@Kilren正是我需要的...... –