sql >> データベース >  >> RDS >> Sqlserver

SQLServerで「最終変更」列を作成する

    一部のデータベーステーブルには、行が最後に更新された日時を格納する「最終変更」列が含まれています。行が更新されるたびに、その更新の日時を反映するように日付が更新されます。

    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から取得できます テーブル。更新が行われる前に、古い行が最初にこのテーブルにコピーされます。


    1. WHMCSデータベースをMariaDBガレラクラスターに移行する方法

    2. SQLServerのLIKEパターンで「単語全体の一致」を検索する

    3. PostgreSQL11の新しいストアドプロシージャの概要

    4. 集計関数SUMを使用してレコードをフィルタリングする方法