2016-10-17 11 views
1

良い日私はSQLに情報を格納する外部プログラムを持っています。そのテーブルのいくつかのフィールドが変更されたときにテーブルを更新するトリガーを実行しようとしています。SQL Trigger To Update

だから私はufAPCHANG1EAMNTufAPHANGE2AMNTufAPCHANGE3AMNT変化に毎回値のいずれかを更新する必要がある1列Contractual Amountを持っています。

人はこれらの値のいずれかまたはすべてを変更することができ、+ 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

あなたのトリガーがある** MAJOR **あなたはそれが呼び出されることになりますと仮定しているように見えるという点で欠陥**一度行ごと* * - それは** **の場合ではありません。トリガは**文ごとに** **起動します。したがって、 'UPDATE'文が25行に影響を与えると、トリガは一度**発生しますが、' Inserted'と 'Deleted'はそれぞれ25行。あなたのコードがここで選択する25行のうちどれですか? 'SELECT ..... FROM INserted' - 非決定的です。これを考慮に入れてトリガーを書き直す必要があります。 –

+0

@marc_sありがとうございますが、これは特定の行を更新するときにチェックすると、挿入された行が1行しかありません。 –

+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

をご確認ください。残念ながら、ジェラルドのコードから残っていました。私は削除する私の答えを編集しました。 ありがとうございました – Kilren

+0

私が必要としていたことを、キンレンにありがとうございました... –