2017-02-19 8 views
0

SQLサーバーでUPDATEトリガーの代わりに、INSERTEDテーブルから値をキャッシュしなくてもすべてのフィールドを更新したいUPDATE Queryのフィールドに移動します。これをどのように行うことができますか?UPDATEトリガーの代わりにすべてのフィールドを動的に更新する方法SQL Server

CREATE TRIGGER trg_Instead_updTable1 ON dbo.Table1 
INSTEAD OF UPDATE 
AS 
BEGIN 
    IF (UPDATE(ID)) 
      RAISERROR ('It is not allowed to update a Table1.ID', 16, 1) 
    ELSE 
      BEGIN 
       UPDATE dbo.Table1 
       SET * = (SELECT * FROM INSERTED JOIN DELETED ON INSERTED.ID = DELETED.ID) 
      END 
END 
+0

ここでは正確に何をしていますか? 'INSTEAD OF UPDATE'トリガは通常、通常の更新ロジックを完全にバイパスし、何か完全なカスタムを行う場合にのみ使用されます。実際にはここで通常の更新ロジックが必要なようです。 – mroach

+0

サイドノート:重大度16の 'raiserror'は更新が行われないようにしません。更新を実際にキャンセルするには、 'rollback transaction'を追加する必要があります。 – mroach

+0

@mroach私はIDの更新を拒否し、他のアップデートを受け入れたいと思っています。これらのコードでは表示されませんが、私は通常のアップデート値にアクセスしようとしていました。何らかの理由であいまいだった –

答えて

1

INSTEAD OF UPDATEトリガーを使用する必要はありません。これらは、すべての通常のテーブル更新ロジックを完全にバイパスし、完全にカスタムを行う場合にのみ必要です。通常、これは複雑なビューにトリガをかけるときに行われます。

値の更新を拒否したいとしました。問題ない。あなたはこれを行うことができます。もちろん

CREATE TRIGGER dbo.Table1_UPDATE on Table1 FOR UPDATE AS 
    IF UPDATE(ID) 
    BEGIN 
    RAISERROR('You may not update the ID', 16, -1) 
    ROLLBACK TRANSACTION 
    RETURN 
    END 
GO 
  1. RAISERROR意志は、彼らが悪い何かをやったユーザに警告、エラーを発生させます。これにより、実行が中止され、更新がロールバックされることが考えられますが、どちらも実行されません(XACT_ABORTONでない場合)。

  2. ROLLBACK TRANSACTIONは、アップデート全体を元に戻し、UPDATEを試行する前の状態にテーブルを復元します。

  3. RETURNトリガーコードを終了します。おそらく、さらなる処理を続ける必要はありません。

あなたはベーステーブルを更新したい場合は、ここにあなたがそれを行う方法は次のとおりです。

UPDATE t1 SET 
     field1 = i.field1, 
     field2 = i.field2, 
     -- all additional fields go here 
FROM Table1 t1 
     INNER JOIN inserted i ON i.id = t1.id 

insertedは新しい値との完全な行全体を含む仮想テーブルです。 deletedには、挿入前の行があります。したがって、どの値が変更されたかを確認するために使用できます。

サイドノート:フィールドがIDENTITYカラムの場合は、それを更新することはできません。そのようなトリガーは不要です。

+2

'UPDATE()'は、値が変更されたかどうかをチェックしません。挿入されたテーブルと削除されたテーブルの値を比較してください。 –