基于程序的审计触发器 table

Procedure based trigger for audit table

我有 2 个 table,一个主 table 和一个审计 table。

create sequence dbo.users_seq;
create table dbo.users 
(
 id bigint primary key default(next value for dbo.users_seq),
 user_data nvarchar(max) not null check(isjson(user_data) = 1),
 timestamp datetime2 not null default sysdatetime(),
 updated_timestamp datetime2 not null default sysdatetime()
);

create sequence dbo.users_audit_seq;
create table dbo.users_audit
(
 id bigint primary key default(next value for dbo.users_audit_seq),
 users_id bigint not null, --id from `users` table
 old nvarchar(max) not null check(isjson(old) = 1), --original row from `users` table
 new nvarchar(max) not null check(isjson(new) = 1), --new row from `users` table
 updated_by varchar(100) not null, --username info
 timestamp datetime2 not null default sysdatetime()
);

我希望在 users 主 table 上创建一个 for update 触发器,它调用一个通用过程,该过程可用于具有类似审计的其他 tables table 架构。

通用程序应写入其审计 table(users table 应写入 users_audit table 但同样的程序也适用于users2 table 并写入 users2_audit table).

注意:临时 tables 方法不起作用

我会先说临时表或 SQL 审计对于这种事情要好得多,你基本上是在重新发明轮子。


尽管如此,下面应该为您提供了一个很好的触发器模型

CREATE OR ALTER TRIGGER TR_users ON users
AFTER INSERT, UPDATE, DELETE
AS

SET NOCOUNT ON;  -- prevent issues with bad client drivers

IF NOT EXISTS (SELECT 1 FROM inserted) AND NOT EXISTS (SELECT 1 FROM deleted)
    RETURN;  -- early bail-out

INSERT users_audit (users_id, old, new, updated_by)
SELECT
  ISNULL(i.id, d.id),
  i.user_data,
  d.user_data,
  SUSER_SNAME()
FROM inserted i
FULL JOIN deleted d ON d.id = i.id  -- full join to match by all primary key columns
WHERE NOT EXISTS (
    SELECT i.user_data    -- add other columns here
    INTERSECT             -- because INTERSECT deals correctly with nulls
    SELECT d.user_data
);

go

如果您想要为每个 table 使用此代码,我强烈建议您不要尝试编写单个动态触发器,而是编写一个可以生成特定触发器和审核 tables 的工具每个 table。请注意,主键可能包含多个列,您需要匹配所有这些列。