Sqlserverエクスプレスを使用していますが、できませんbefore updated
引き金。他の方法がありますか?
MSSQLはBEFORE
トリガーをサポートしていません。最も近いのはINSTEAD OF
はトリガーしますが、その動作はMySQLのBEFORE
トリガーの動作とは異なります。
それらの詳細については、こちらをご覧ください こちら 、およびINSTEAD OF
triggers「トリガーSQLステートメントの代わりにトリガーが実行されることを指定し、トリガーステートメントのアクションをオーバーライドします。」したがって、トリガーが適切に記述/処理されていない場合、更新に対するアクションが実行されない場合があります。カスケードアクションも影響を受けます。
代わりに、達成しようとしているものに対して異なるアプローチを使用することもできます。
MSSQLには「前トリガー」がないことは事実です。ただし、「挿入」テーブルと「削除」テーブルを一緒に使用することで、テーブルで行われた変更を追跡できます。更新によりトリガーが起動されると、「挿入」テーブルに新しい値が保存され、「削除」テーブルに古い値が保存されます。この情報を取得すると、「トリガー前」の動作を比較的簡単にシミュレートできます。
これがSQL ServerExpressに適用されるかどうかはわかりませんが、更新後にトリガーが発生している場合でも「前」のデータにアクセスできます。 deletedまたはinsertedテーブルからデータを読み取る必要がありますテーブルが変更されると、その場で作成されます。これは本質的に@Stamenが言っていることですが、その(役に立つ!)答えを理解するためにさらに探求する必要がありました。
deletedテーブルには、DELETEおよびUPDATEステートメント中に影響を受ける行のコピーが格納されます。 DELETEまたはUPDATEステートメントの実行中に、行がトリガーテーブルから削除され、削除されたテーブルに転送されます...
insertedテーブルには、INSERTおよびUPDATEステートメント中に影響を受ける行のコピーが格納されます。挿入または更新トランザクション中に、挿入されたテーブルとトリガーテーブルの両方に新しい行が追加されます...
そのため、これらのテーブルの1つからデータを読み取るトリガーを作成できます。
CREATE TRIGGER <TriggerName> ON <TableName>
AFTER UPDATE
AS
BEGIN
INSERT INTO <HistoryTable> ( <columns...>, DateChanged )
SELECT <columns...>, getdate()
FROM deleted;
END;
私の例は、次の例に基づいています。
T-SQLはAFTERおよびINSTEAD OFトリガーのみをサポートします。他のRDBMSに見られるように、BEFOREトリガーは機能しません。
INSTEAD OFトリガーを使用したいと思うと思います。
SQL Serverのすべての「通常」トリガーは、「AFTER ...」トリガーです。 「BEFORE ...」トリガーはありません。
更新前に何かを行うには、 INSTEAD OF UPDATE Triggers をチェックしてください。
BEFORE UPDATE
SQL Serverでは、トリックを使用します。レコードの誤った更新を行います(UPDATE Table SET Field = Field
)、このようにして、レコードの前の画像を取得します。
代わりにトリガーを使用する場合、トリガーで特に指示しない限り、挿入をコミットしないことに注意してください。実際に行う代わりに、通常の操作の代わりにこれを行うため、通常の挿入アクションは発生しません。
完全な例:
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