简体   繁体   English

触发以记录插入/更新/删除的值SQL Server 2016

[英]Trigger to log inserted/updated/deleted values SQL Server 2016

The application adds/updates/deletes rows to table X. Sample below. 该应用程序向表X添加/更新/删除行。下面的示例。

|ID|Type*|Name |Value|Description
|1 |1    |Mike |100  |-
|2 |1    |John |50   |-
|3 |1    |Vince|10   |-

*Column Type = 1 - this is data from application *列类型= 1-这是来自应用程序的数据

Column Type = 2 - this will be log data 列类型= 2-这将是日志数据

I need trigger to log inserted/updated/deleted values also in a table X. 我还需要触发器来在表X中也记录插入/更新/删除的值。

For example when change in application row number 2 and 3: 例如,当更改应用程序行2和3时:

|ID|Type|Name  |Value|Description
|2 |1   |Monica|60   |-
|3 |1   |Tom   |5    |-

The result on table X should be like this: 表X上的结果应如下所示:

|ID|Type|Name  |Value|Description
|1 |1   |Mike  |100  |-
|2 |1   |Monica|60   |-
|3 |1   |Tom   |5    |-
|4 |2   |Monica|60   |UPDATE OPERATION
|5 |2   |Tom   |5    |UPDATE OPERATION

When the application adds another row: 当应用程序添加另一行时:

|ID|Type|Name  |Value|Description
|6 |1   |Paul  |200  |-

The result on table X should be like this: 表X上的结果应如下所示:

|ID|Type|Name  |Value|Description
|1 |1   |Mike  |100  |-
|2 |1   |Monica|60   |-
|3 |1   |Tom   |5    |-
|4 |2   |Monica|60   |UPDATE OPERATION
|5 |2   |Tom   |5    |UPDATE OPERATION
|6 |1   |Paul  |200  |-
|7 |2   |Paul  |200  |INSERT OPERATION

... ...

I think the most straightforward way to do this is via instead of triggers, and to use separate triggers for each operation. 我认为最简单的方法是通过instead of触发器,并对每个操作使用单独的触发器。 I think that these are correct: 我认为这些是正确的:

create table X(ID int not null,Type int not null, Name varchar(11) not null, 
               Value int not null, Description varchar(38) not null);
insert into X(ID,Type,Name,Value,Description) values
(1,1,'Mike' ,100,'-'),
(2,1,'John' ,50 ,'-'),
(3,1,'Vince',10 ,'-');
go
create table Numbers (n int not null);
insert into Numbers(n) values (1),(2),(3); --TODO - May need more in future
go
create trigger T_X_I on X instead of insert
as
    set nocount on;
    insert into X(ID,Type,Name,Value,Description)
    select i.ID,n.n,i.Name,i.Value,
       CASE WHEN n.n = 1 THEN i.Description ELSE 'INSERT' END
    from inserted i
        cross join
        Numbers n
    where n.n in (1,2);
go
create trigger T_X_U on X instead of update
as
    set nocount on;
    merge into X
    using (select * from inserted i cross join Numbers n where n.n in (1,2)) s
    on
        s.ID = X.ID and
        s.n = 1 and
        X.Type = 1
    when matched then update
       set Name = s.Name,Value = s.Value,Description = s.Description
    when not matched then
       insert (ID,Type,Name,Value,Description) values 
              (s.ID,s.n,s.Name,s.Value,'UPDATE');
go
create trigger T_X_D on X instead of delete
as
    set nocount on;
    merge into X
    using (select * from deleted d cross join Numbers n where n.n in (1,2)) s
    on
        s.ID = X.ID and
        s.n = 1 and
        X.Type = 1
    when matched then delete
    when not matched then
      insert (ID,Type,Name,Value,Description) values 
             (s.ID,s.n,s.Name,s.Value,'DELETE');
go
update X set
    Name = CASE WHEN ID=2 THEN 'Monica' ELSE 'Tom' END,
    Value = CASE WHEN ID=2 THEN 60 ELSE 5 END
where ID in (2,3)
go
insert into X (ID,Type,Name,Value,Description)
values (6,1,'Paul',200,'-')
go
select * from X

Results: 结果:

ID          Type        Name        Value       Description
----------- ----------- ----------- ----------- --------------------------------------
1           1           Mike        100         -
2           1           Monica      60          -
3           1           Tom         5           -
2           2           Monica      60          UPDATE
3           2           Tom         5           UPDATE
6           1           Paul        200         -
6           2           Paul        200         INSERT

If you already have a Numbers table or equivalent, feel free to replace that in the above queries. 如果您已经有一个Numbers表或等效表,请随时在上面的查询中替换它。

What problem do you face ?. 您遇到什么问题?

Those triggers are quite simple: 这些触发器非常简单:

CREATE TRIGGER [MY_TABLE_Inserts] ON MY_TABLE AFTER INSERT
AS 
BEGIN
  insert into MY_TABLE (TYPE, NAME, VALUE, DESCRIPTION)
         select 2, NAME, VALUE, 'INSERT OPERATION'
         from inserted
         where TYPE = 1;
END

CREATE TRIGGER [MY_TABLE_Inserts] ON MY_TABLE AFTER UPDATE
AS 
BEGIN
  insert into MY_TABLE (TYPE, NAME, VALUE, DESCRIPTION)
         select 2, NAME, VALUE, 'UPDATE OPERATION'
         from inserted
         where TYPE = 1;
END

CREATE TRIGGER [MY_TABLE_Inserts] ON MY_TABLE AFTER DELETE
AS 
BEGIN
  insert into MY_TABLE (TYPE, NAME, VALUE, DESCRIPTION)
         select 2, NAME, VALUE, 'DELETE OPERATION'
         from deleted
         where TYPE = 1;
END

Doesn't something like that works for you ?. 这样的东西对您不起作用吗?

By the way, the WHERE TYPE = 1; 顺便说一句,WHERE TYPE = 1; prevents to re-log your logging operations. 防止重新记录您的记录操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM