一部のデータベーステーブルには、行が最後に更新された日時を格納する「最終変更」列が含まれています。行が更新されるたびに、その更新の日時を反映するように日付が更新されます。
SQL Serverでは、トリガーを使用してこの更新を実行できます。
トリガーは、データベースサーバーでイベントが発生したときに自動的に実行される特殊なタイプのストアドプロシージャです。
CREATE TRIGGER
を使用できます T-SQLを使用するときにトリガーを作成するステートメント。このステートメントを使用して、DML、DDL、またはログオントリガーを作成できます。
例
次のコードは、テーブルと、 ModifiedDate
を更新するトリガーを作成します。 更新があるときはいつでも列。
CREATE TABLE dbo.Books (
BookId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
BookName nvarchar(1000) NOT NULL,
CreateDate datetime DEFAULT CURRENT_TIMESTAMP,
ModifiedDate datetime DEFAULT CURRENT_TIMESTAMP
);
CREATE TRIGGER trg_Books_UpdateModifiedDate
ON dbo.Books
AFTER UPDATE
AS
UPDATE dbo.Books
SET ModifiedDate = CURRENT_TIMESTAMP
WHERE BookId IN (SELECT DISTINCT BookId FROM inserted);
行を挿入
行を挿入して選択し、 DEFAULT
の結果を確認しましょう。 制約:
INSERT INTO Books (BookName)
VALUES ('Trigger Happy');
SELECT * FROM Books;
結果(垂直出力を使用):
-[ RECORD 1 ]------------------------- BookId | 1 BookName | Trigger Happy CreateDate | 2020-08-17 23:33:15.230 ModifiedDate | 2020-08-17 23:33:15.230
これは、読みやすくするために垂直出力を使用して表示されます(したがって、すべての列を読み取るために横にスクロールする必要はありません)。
この場合、両方の CreatedDate
およびModifiedDate
列には同じ値が含まれています。ただし、行が更新されると、 ModifiedDate
の値が変わるはずです。そのため、トリガーを作成しました。
行を更新
次に、行を更新して結果を選択しましょう。
UPDATE Books
SET BookName = 'Trigger Hippy'
WHERE BookId = 1;
SELECT * FROM Books;
結果(垂直出力を使用):
-[ RECORD 1 ]------------------------- BookId | 1 BookName | Trigger Hippy CreateDate | 2020-08-17 23:33:15.230 ModifiedDate | 2020-08-18 00:07:39.680
予想どおり、 ModifiedDate
列は更新されますが、 CreateDate
列は同じままです。
コードの詳細な説明
以下は、テーブルとそれに関連するトリガーの作成に使用されるコードの詳細な説明です。
テーブル
次のコードはテーブルを作成します:
CREATE TABLE dbo.Books (
BookId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
BookName nvarchar(1000) NOT NULL,
CreateDate datetime DEFAULT CURRENT_TIMESTAMP,
ModifiedDate datetime DEFAULT CURRENT_TIMESTAMP
);
ModifiedDate
列にはDEFAULT
があります デフォルト値をCURRENT_TIMESTAMP
に設定する制約 ( CreateDate
も同様です 列)。
これは、行が最初に挿入されたときに、 CURRENT_TIMESTAMP
が それらの列に挿入されます。
これは最初の挿入には問題ありませんが、その後の更新には対応していません。そこでトリガーが登場します。
トリガー
次のコードはトリガーを作成します:
CREATE TRIGGER trg_Books_UpdateModifiedDate
ON dbo.Books
AFTER UPDATE
AS
UPDATE dbo.Books
SET ModifiedDate = CURRENT_TIMESTAMP
WHERE BookId IN (SELECT DISTINCT BookId FROM inserted);
この場合、トリガーを trg_Books_UpdateModifiedDate
と呼びました。 。
dbo.Books
で作成しました データベースであり、すべての UPDATE
の後に実行されます 。
実行すると、 ModifiedDate
が更新されます。 CURRENT_TIMESTAMP
への列 (もちろん、更新された行のみです)。
insert
をチェックすることで、どの行が更新されたかを判断できます テーブル。 挿入コード> tableは、SQLServerが作成および維持する一時的なメモリ常駐テーブルです。
挿入コード> テーブルには、
INSERT
中に影響を受ける行のコピーが格納されます およびUPDATE
ステートメント。挿入または更新トランザクション中に、新しい行が両方の insert
に追加されます テーブルとトリガーテーブル。 挿入された
の行 テーブルは、トリガーテーブルの新しい行のコピーです。
挿入
に加えて テーブルでは、SQLServerはdeleted
も作成および維持します テーブル。更新トランザクションは、削除操作とそれに続く挿入操作に似ています。古い行はdeleted
にコピーされます 最初にテーブルを作成し、次に新しい行をトリガーテーブルと insert
にコピーします テーブル。
「作成日」列のトリガー
DEFAULT
を使用する 制約は初期値を作成するための便利な方法ですが、誰かが後でその値を直接更新する可能性があるというリスクがあります。
これが問題であると思われる場合は、トリガーを変更して[作成日]列を含めることができます。これにより、行が更新されるたびに元の値にリセットされます。
元の値はdeleted
から取得できます テーブル。更新が行われる前に、古い行が最初にこのテーブルにコピーされます。