MW211 EXIT

devlog
MSSQL/ジャーナル
2018年10月30日
┌──────────────────────────────────────┐
│CREATE TABLE [DB].[dbo].[T_表] (                                            │
│    [キー]          [int]               NOT NULL,                           │
│    [値]            [nvarchar](256)     NULL,                               │
│    [更新者]        [nvarchar](32)      NOT NULL,                           │
│    [更新日時]      [datetime]          NOT NULL    DEFAULT (GETDATE()),    │
│    CONSTRAINT [PK_表] PRIMARY KEY CLUSTERED (                              │
│        [キー]                  ASC                                         │
│    )                                                                       │
│);                                                                          │
└──────────────────────────────────────┘
例えば上記テーブルのジャーナルテーブル(更新履歴テーブル)を実装する方法。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【1】ジャーナルテーブルを作る
┌──────────────────────────────────────┐
│CREATE TABLE [DB].[dbo].[T_ジャーナル_表] (                                 │
│    [ジャーナルID]      [int] IDENTITY(1,1) NOT NULL,                   --※│
│    [ジャーナル区分]    [nchar](2)          NOT NULL,                   --※│
│    [キー]              [int]               NULL,                           │
│    [値]                [nvarchar](256)     NULL,                           │
│    [更新者]            [nvarchar](32)      NULL,                           │
│    [更新日時]          [datetime]          NULL,                           │
│    CONSTRAINT [PK_ジャーナル_表] PRIMARY KEY CLUSTERED (                   │
│        [ジャーナルID]          ASC                                     --※│
│    )                                                                       │
│);                                                                          │
└──────────────────────────────────────┘
  対象テーブルの各列について、制約を一切はずして、継承する。
  また、代わりに主キーとして連番([ジャーナルID])をあてる。
  それと、「追加」か「削除」を記録する区分([ジャーナル区分])も設置。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【2】トリガを仕込む
┌──────────────────────────────────────┐
│CREATE TRIGGER [dbo].[TRIGGER_ジャーナル_表] ON [DB].[dbo].[T_表]           │
│    AFTER INSERT, UPDATE, DELETE                                            │
│AS                                                                          │
│BEGIN                                                                       │
│    INSERT INTO [DB].[dbo].[T_ジャーナル_表] (                              │
│            [ジャーナル区分],                                               │
│            [キー],                                                         │
│            [値],                                                           │
│            [更新者],                                                       │
│            [更新日時]                                                      │
│        )                                                                   │
│        SELECT '削除' AS [ジャーナル区分],                                  │
│               [キー],                                                      │
│               [値],                                                        │
│               [更新者],                                                    │
│               [更新日時]                                                   │
│            FROM deleted;                                                   │
│    INSERT INTO [DB].[dbo].[T_ジャーナル_表] (                              │
│            [ジャーナル区分],                                               │
│            [キー],                                                         │
│            [値],                                                           │
│            [更新者],                                                       │
│            [更新日時]                                                      │
│        )                                                                   │
│        SELECT '追加' AS [ジャーナル区分],                                  │
│               [キー],                                                      │
│               [値],                                                        │
│               [更新者],                                                    │
│               [更新日時]                                                   │
│            FROM inserted;                                                  │
│END;                                                                        │
└──────────────────────────────────────┘
  MSSQLの場合は、「deleted」で更新前(削除前)のレコードが、
  「inserted」で更新後(追加後)のレコードが取得できるので
  それをそのままジャーナルにしてしまった方が間違いないようだ。

  もちろん、INSERT・UPDATE・DELETEに分けるという方法もあるが
  一つのトリガ内で、これを(何をトリガとしたのかを)識別することは難しい模様。
  そうなると、トリガを三つ用意した方が間違いないようではあるが。。。
分類:MSSQL