web-dev-qa-db-ja.com

SQLサーバーでBEFORE UPDATEDトリガーを実行するにはどうすればよいですか?

Sqlserverエクスプレスを使用していますが、できませんbefore updated 引き金。他の方法がありますか?

40
Bigballs

MSSQLはBEFOREトリガーをサポートしていません。最も近いのはINSTEAD OFはトリガーしますが、その動作はMySQLのBEFOREトリガーの動作とは異なります。

それらの詳細については、こちらをご覧ください こちら 、およびINSTEAD OF triggers「トリガーSQLステートメントの代わりにトリガーが実行されることを指定し、トリガーステートメントのアクションをオーバーライドします。」したがって、トリガーが適切に記述/処理されていない場合、更新に対するアクションが実行されない場合があります。カスケードアクションも影響を受けます。

代わりに、達成しようとしているものに対して異なるアプローチを使用することもできます。

36
achinda99

MSSQLには「前トリガー」がないことは事実です。ただし、「挿入」テーブルと「削除」テーブルを一緒に使用することで、テーブルで行われた変更を追跡できます。更新によりトリガーが起動されると、「挿入」テーブルに新しい値が保存され、「削除」テーブルに古い値が保存されます。この情報を取得すると、「トリガー前」の動作を比較的簡単にシミュレートできます。

33
Stamen

これがSQL ServerExpressに適用されるかどうかはわかりませんが、更新後にトリガーが発生している場合でも「前」のデータにアクセスできます。 deletedまたはinsertedテーブルからデータを読み取る必要がありますテーブルが変更されると、その場で作成されます。これは本質的に@Stamenが言っていることですが、その(役に立つ!)答えを理解するためにさらに探求する必要がありました。

deletedテーブルには、DELETEおよびUPDATEステートメント中に影響を受ける行のコピーが格納されます。 DELETEまたはUPDATEステートメントの実行中に、行がトリガーテーブルから削除され、削除されたテーブルに転送されます...

insertedテーブルには、INSERTおよびUPDATEステートメント中に影響を受ける行のコピーが格納されます。挿入または更新トランザクション中に、挿入されたテーブルとトリガーテーブルの両方に新しい行が追加されます...

https://msdn.Microsoft.com/en-us/library/ms191300.aspx

そのため、これらのテーブルの1つからデータを読み取るトリガーを作成できます。

CREATE TRIGGER <TriggerName> ON <TableName>
AFTER UPDATE
AS
  BEGIN
    INSERT INTO <HistoryTable> ( <columns...>, DateChanged )
    SELECT <columns...>, getdate()
    FROM deleted;
  END;

私の例は、次の例に基づいています。

http://www.seemoredata.com/en/showthread.php?134-Example-of-BEFORE-UPDATE-trigger-in-Sql-Server-good-for-Type-2-dimension-table-更新

sql-serverトリガー

9
Charlie Joynt

T-SQLはAFTERおよびINSTEAD OFトリガーのみをサポートします。他のRDBMSに見られるように、BEFOREトリガーは機能しません。

INSTEAD OFトリガーを使用したいと思うと思います。

8
Ian Nelson

SQL Serverのすべての「通常」トリガーは、「AFTER ...」トリガーです。 「BEFORE ...」トリガーはありません。

更新前に何かを行うには、 INSTEAD OF UPDATE Triggers をチェックしてください。

3
Tomalak

BEFORE UPDATE SQL Serverでは、トリックを使用します。レコードの誤った更新を行います(UPDATE Table SET Field = Field)、このようにして、レコードの前の画像を取得します。

2
Luciano

代わりにトリガーを使用する場合、トリガーで特に指示しない限り、挿入をコミットしないことに注意してください。実際に行う代わりに、通常の操作の代わりにこれを行うため、通常の挿入アクションは発生しません。

1
HLGEM

完全な例:

CREATE TRIGGER [dbo].[trig_020_Original_010_010_Gamechanger]
   ON  [dbo].[T_Original]
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    DECLARE @Old_Gamechanger int;
    DECLARE @New_Gamechanger int;

    -- Insert statements for trigger here
    SELECT @Old_Gamechanger = Gamechanger from DELETED;
    SELECT @New_Gamechanger = Gamechanger from INSERTED;

    IF @Old_Gamechanger != @New_Gamechanger

        BEGIN

            INSERT INTO [dbo].T_History(ChangeDate, Reason, Callcenter_ID, Old_Gamechanger, New_Gamechanger)
            SELECT GETDATE(), 'Time for a change', Callcenter_ID, @Old_Gamechanger, @New_Gamechanger
                FROM deleted
            ;

        END

END
0
Nick Oetjen