2017-07-07 118 views
0

應用程序向表X添加/更新/刪除行。下面的示例。觸發記錄插入/更新/刪除的值SQL Server 2016

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

*列類型= 1 - 這是從應用程序數據

列類型= 2 - 這將是記錄數據

我需要觸發登錄插入/更新/刪除的值也在表X.

例如,當更改應用程序行號2和3時:

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

上表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 

當應用程序添加另一行:

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

上表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 

...

+0

我假設你已經考慮並拒絕了更傳統的方法,如時態表或使用單獨的表進行審計。 –

+0

請張貼你的觸發器。你得到什麼錯誤? – Peter

回答

1

我認爲最直接的方法是通過instead of觸發器,併爲每個操作使用單獨的觸發器。我認爲這些都是正確的:

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 

結果:

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 

如果你已經有了一個Numbers表或等價物,隨意更換,在上面的查詢。

+0

它完美的作品,很好的解釋! – Najlepszak

0

你面臨什麼問題?

這些觸發器是非常簡單的:

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 

沒有類似的東西爲你工作?

順便說一下,WHERE TYPE = 1;阻止重新記錄您的日誌記錄操作。