44

これらの要件が標準であるかどうかはわかりませんが、次のことを実行できるソリューションがあるかどうか疑問に思っています。

  • 指定された一連のテーブルについて、関連するテーブルの監査バージョンでレコードを変更する前に、レコードのコピーを保持します。

すべてのテーブルに対してこれをコーディングする必要はありません。これを行う SQL Server の上にインストールできるソリューションがあるかどうか疑問に思っていますか?

4

8 に答える 8

12

データベース テーブル

次のクラス図に示すようにBook、監査ログ情報をテーブルに格納する必要があるテーブルがあるとします。BookAuditLog

トリガーを使用した SQL Server 監査ログ

BookAuditLogテーブルは次のように作成されます。

CREATE TABLE BookAuditLog (
    BookId bigint NOT NULL,
    OldRowData nvarchar(1000) CHECK(ISJSON(OldRowData) = 1),
    NewRowData nvarchar(1000) CHECK(ISJSON(NewRowData) = 1),
    DmlType varchar(10) NOT NULL CHECK (DmlType IN ('INSERT', 'UPDATE', 'DELETE')),
    DmlTimestamp datetime NOT NULL,
    DmlCreatedBy varchar(255) NOT NULL,
    TrxTimestamp datetime NOT NULL,
    PRIMARY KEY (BookId, DmlType, DmlTimestamp)
) 

テーブルのBookAuditLog列には、次のデータが格納されます。

  • この列には、このログ イベントが作成されBookIdた関連行の識別子が格納されます。Book
  • は、INSERT、UPDATE、または DELETE ステートメントを実行する前に、レコード状態OldRowDataの JSON 表現を格納します。Book
  • は、INSERT、UPDATE、または DELETE ステートメントが実行された後NewRowDataのレコード状態の JSON 表現を格納します。Book
  • は、特定の行DmlTypeを作成、更新、または削除した DML ステートメント タイプを格納する列挙列ですBook
  • DmlTimestamp、DML ステートメントの実行タイムスタンプを格納します。
  • DmlCreatedByINSERT、UPDATE、または DELETE DML ステートメントを発行したユーザーを格納します。
  • は、レコードTrxTimestampを変更したトランザクションのタイムスタンプを保存します。Book

INSERT、UPDATE、および DELETE トリガー

INSERT、UPDATE、および DELETE DML ステートメントをキャプチャするには、BookAuditLogテーブルにレコードを挿入する 3 つのデータベース トリガーを作成する必要があります。

Bookテーブルの INSERT ステートメントをインターセプトするために、TR_Book_Insert_AuditLogトリガーを作成します。

CREATE TRIGGER TR_Book_Insert_AuditLog ON Book
FOR INSERT AS 
BEGIN
    DECLARE @loggedUser varchar(255)
    SELECT @loggedUser = CAST(SESSION_CONTEXT(N'loggedUser') AS varchar(255))
    
    DECLARE @transactionTimestamp datetime = SYSUTCdatetime()
    
    INSERT INTO BookAuditLog (
        BookId,
        OldRowData,
        NewRowData,
        DmlType,
        DmlTimestamp,
        DmlCreatedBy,
        TrxTimestamp
    )
    VALUES(
        (SELECT id FROM Inserted),
        null,
        (SELECT * FROM Inserted FOR JSON PATH, WITHOUT_ARRAY_WRAPPER),
        'INSERT',
        CURRENT_TIMESTAMP,
        @loggedUser,
        @transactionTimestamp
    );
END

Bookレコードの UPDATE ステートメントを取得するために、次のTR_Book_Update_AuditLogトリガーを作成します。

CREATE TRIGGER TR_Book_Update_AuditLog ON Book
FOR UPDATE AS 
BEGIN
    DECLARE @loggedUser varchar(255)
    SELECT @loggedUser = CAST(SESSION_CONTEXT(N'loggedUser') AS varchar(255))
    
    DECLARE @transactionTimestamp datetime = SYSUTCdatetime()
    
    INSERT INTO BookAuditLog (
        BookId,
        OldRowData,
        NewRowData,
        DmlType,
        DmlTimestamp,
        DmlCreatedBy,
        TrxTimestamp
    )
    VALUES(
        (SELECT id FROM Inserted),
        (SELECT * FROM Deleted FOR JSON PATH, WITHOUT_ARRAY_WRAPPER),
        (SELECT * FROM Inserted FOR JSON PATH, WITHOUT_ARRAY_WRAPPER),
        'UPDATE',
        CURRENT_TIMESTAMP,
        @loggedUser,
        @transactionTimestamp
    );
END

Bookテーブル行の DELETE ステートメントをインターセプトするために、次のTR_Book_Delete_AuditLogトリガーを作成します。

CREATE TRIGGER TR_Book_Delete_AuditLog ON Book
FOR DELETE AS 
BEGIN
    DECLARE @loggedUser varchar(255)
    SELECT @loggedUser = CAST(SESSION_CONTEXT(N'loggedUser') AS varchar(255))
    
    DECLARE @transactionTimestamp datetime = SYSUTCdatetime()
    
    INSERT INTO BookAuditLog (
        BookId,
        OldRowData,
        NewRowData,
        DmlType,
        DmlTimestamp,
        DmlCreatedBy,
        TrxTimestamp
    )
    VALUES(
        (SELECT id FROM Deleted),
        (SELECT * FROM Deleted FOR JSON PATH, WITHOUT_ARRAY_WRAPPER),
        null,
        'DELETE',
        CURRENT_TIMESTAMP,
        @loggedUser,
        @transactionTimestamp
    );
END

デモタイム

Bookテーブルで INSERT ステートメントを実行する場合:

INSERT INTO Book (
    Author, 
    PriceInCents, 
    Publisher, 
    Title, 
    Id
)
VALUES (
    'Vlad Mihalcea', 
    3990, 
    'Amazon', 
    'High-Performance Java Persistence 1st edition', 
    1
)

テーブルBookAuditLogで実行されたばかりの INSERT ステートメントをキャプチャするレコードが挿入されていることがわかります。Book

| BookId | OldRowData | NewRowData                                                                                                                         | DmlType | DmlTimestamp            | DmlCreatedBy  | TrxTimestamp            |
|--------|------------|------------------------------------------------------------------------------------------------------------------------------------|---------|-------------------------|---------------|-------------------------|
| 1      |            | {"Id":1,"Author":"Vlad Mihalcea","PriceInCents":3990,"Publisher":"Amazon","Title":"High-Performance Java Persistence 1st edition"} | INSERT  | 2020-11-08 08:40:28.343 | Vlad Mihalcea | 2020-11-08 06:40:28.347 |

Book表の行を更新する場合:

UPDATE Book 
SET PriceInCents = 4499 
WHERE Id = 1

テーブルBookAuditLogの AFTER UPDATE トリガーによって新しいレコードが追加されることがわかります。Book

| BookId | OldRowData                                                                                                                         | NewRowData                                                                                                                         | DmlType | DmlTimestamp            | DmlCreatedBy  | TrxTimestamp            |
|--------|------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|---------|-------------------------|---------------|-------------------------|
| 1      |                                                                                                                                    | {"Id":1,"Author":"Vlad Mihalcea","PriceInCents":3990,"Publisher":"Amazon","Title":"High-Performance Java Persistence 1st edition"} | INSERT  | 2020-11-08 08:40:28.343 | Vlad Mihalcea | 2020-11-08 06:40:28.347 |
| 1      | {"Id":1,"Author":"Vlad Mihalcea","PriceInCents":3990,"Publisher":"Amazon","Title":"High-Performance Java Persistence 1st edition"} | {"Id":1,"Author":"Vlad Mihalcea","PriceInCents":4499,"Publisher":"Amazon","Title":"High-Performance Java Persistence 1st edition"} | UPDATE  | 2020-11-08 08:43:22.803 | Vlad Mihalcea | 2020-11-08 06:43:22.807 |

Book表の行を削除する場合:

DELETE FROM Book 
WHERE Id = 1

テーブルBookAuditLogの AFTER DELETE トリガーによって新しいレコードが追加されます。Book

| BookId | OldRowData                                                                                                                         | NewRowData                                                                                                                         | DmlType | DmlTimestamp            | DmlCreatedBy  | TrxTimestamp            |
|--------|------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|---------|-------------------------|---------------|-------------------------|
| 1      |                                                                                                                                    | {"Id":1,"Author":"Vlad Mihalcea","PriceInCents":3990,"Publisher":"Amazon","Title":"High-Performance Java Persistence 1st edition"} | INSERT  | 2020-11-08 08:40:28.343 | Vlad Mihalcea | 2020-11-08 06:40:28.347 |
| 1      | {"Id":1,"Author":"Vlad Mihalcea","PriceInCents":3990,"Publisher":"Amazon","Title":"High-Performance Java Persistence 1st edition"} | {"Id":1,"Author":"Vlad Mihalcea","PriceInCents":4499,"Publisher":"Amazon","Title":"High-Performance Java Persistence 1st edition"} | UPDATE  | 2020-11-08 08:43:22.803 | Vlad Mihalcea | 2020-11-08 06:43:22.807 |
| 1      | {"Id":1,"Author":"Vlad Mihalcea","PriceInCents":4499,"Publisher":"Amazon","Title":"High-Performance Java Persistence 1st edition"} |                                                                                                                                    | DELETE  | 2020-11-08 08:44:25.630 | Vlad Mihalcea | 2020-11-08 06:44:25.633 |
于 2020-11-28T12:51:25.697 に答える
6

ApexSQL Auditなどのサード パーティ製のポイント アンド クリック トリガー ベースのソリューションを試すことができます。ApexSQL Auditは SQL Server データベース用の監査ツールであり、データベースで発生したデータ変更を、誰が変更したか、どのオブジェクトが変更されたかに関する情報を含めてキャプチャします。いつ変更されたか、および変更に使用された SQL ログイン、アプリケーション、およびホストに関する情報。キャプチャされたすべての情報を中央リポジトリに保存し、印刷に適した形式でエクスポートします

免責事項: 私は ApexSQL で製品サポート エンジニアとして働いています。

于 2014-04-04T17:40:00.900 に答える
0

この記事をご覧ください - SQL Server 2008 での監査では、 SQL Server 2008 に既に存在する監査機能を見事に活用しています。

また、@Microtechie の回答が素晴らしい記事を示していることにも言及する必要があります。それらを読んで、どちらが適応しやすいかを判断してください。

于 2013-07-09T11:36:12.053 に答える
0

トリガーを見てください。これらを使用して、要件に合わせて何かを実装できます。

于 2013-07-09T11:05:09.313 に答える
-1

データベース スナップショットを使用すると、データの読み取り専用コピーをその瞬間に保持できます。また、ログのバックアップを使用すると、必要に応じて特定の期間に情報を復元できます。

ログから情報を読み取って、変更された情報を取得することもできます。

あなたの好みではない他の解決策は、トリガーを使用して変更を追跡することですが、各テーブルで作業する必要がある場合があります。Change Data Capture 機能を有効にして変更を検出することもできます。この機能もテーブルごとに有効にする必要がありますが、必要なコードはトリガーよりも少なくなります。

最後に、 Apex SQL Triggerのような、数回のクリックと構成で自動的にこのジョブを実行するサードパーティ ツールがあります。

于 2015-01-29T23:02:21.287 に答える