How to copy an inserted,updated,deleted row in a SQL Server trigger(s)

人走茶凉 提交于 2019-12-31 10:46:11

问题


If a user changes table HelloWorlds, then I want 'action they did', time they did it, and a copy of the original row insert into HelloWorldsHistory.

I would prefer to avoid a separate triggers for insert, update, and delete actions due to the column lengths.

I've tried this:

create trigger [HelloWorlds_After_IUD] on [HelloWorlds]
FOR insert, update, delete
as
if @@rowcount = 0 
return
if exists (select 1 from inserted) and not exists (select 1 from deleted)
begin
insert into HelloWorldHistory (hwh_action, ..long column list..)
select 'INSERT', helloWorld.id, helloWorld.text ... and more from inserted
end
else
    if exists (select 1 from inserted) and exists (select 1 from deleted)
    begin
insert into HelloWorldHistory (hwh_action, ..long column list..)
select 'UPDATE', helloWorld.id, helloWorld.text ... and more from deleted 
    end
    else
    begin
insert into HelloWorldHistory (hwh_action, ..long column list..)
select 'DELETE', helloWorld.id, helloWorld.text ... and more from deleted
    end
end

I've never seen an insert appear, but I've seen updates. I'm going to try 3 separate triggers, though maintaining the column lists will not be fun.


回答1:


try something like this:

CREATE TRIGGER YourTrigger ON YourTable
   AFTER INSERT,UPDATE,DELETE
AS

DECLARE @HistoryType    char(1) --"I"=insert, "U"=update, "D"=delete

SET @HistoryType=NULL

IF EXISTS (SELECT * FROM INSERTED)
BEGIN
    IF EXISTS (SELECT * FROM DELETED)
    BEGIN
        --UPDATE
        SET @HistoryType='U'
    END
    ELSE
    BEGIN
        --INSERT
        SET @HistoryType='I'
    END
    --handle insert or update data
    INSERT INTO YourLog
            (ActionType,ActionDate,.....)
        SELECT
            @HistoryType,GETDATE(),.....
            FROM INSERTED

END
ELSE IF EXISTS(SELECT * FROM DELETED)
BEGIN
    --DELETE
    SET @HistoryType='D'

    --handle delete data, insert into both the history and the log tables
    INSERT INTO YourLog
            (ActionType,ActionDate,.....)
        SELECT
            @HistoryType,GETDATE(),.....
            FROM DELETED

END
--ELSE
--BEGIN
--    both INSERTED and DELETED are empty, no rows affected
--END



回答2:


You need to associate (match) the rows in the inserted and deleted columns. Something like this should work better.

create trigger [HelloWorlds_After_IUD] on [HelloWorlds]
FOR insert, update, delete
as

insert into HeloWorldsHistory
select 'INSERT', helloWorld.id, helloWorld.text ... and more 
from inserted
where myKeyColumn not in (select myKeyColumn from deleted)

insert into HeloWorldsHistory
select 'DELETE', helloWorld.id, helloWorld.text ... and more 
from deleted
where myKeyColumn not in (select myKeyColumn from inserted)

insert into HeloWorldsHistory
select 'UPDATE', helloWorld.id, helloWorld.text ... and more 
from inserted
where myKeyColumn in (select myKeyColumn from deleted)


来源:https://stackoverflow.com/questions/4391393/how-to-copy-an-inserted-updated-deleted-row-in-a-sql-server-triggers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!