2017-07-07 4 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;ログ操作を再ログするのを防ぎます。

関連する問題