Как скопировать вставленную, обновленную и удаленную строку в триггер (ы) SQL Server - PullRequest
8 голосов
/ 08 декабря 2010

Если пользователь изменяет таблицу HelloWorlds, тогда я хочу «действие, которое он совершил», время, когда он это сделал, и копию оригинальной строки вставьте в HelloWorldsHistory.

Я бы предпочел избегать отдельных триггеров для операций вставки, обновления и удаления из-за длины столбцов.

Я пробовал это:

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

Я никогда не видел вставки, но видел обновления. Я собираюсь попробовать 3 отдельных триггера, хотя поддержание списков столбцов не будет забавным.

Ответы [ 2 ]

19 голосов
/ 08 декабря 2010

попробуйте что-то вроде этого:

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
6 голосов
/ 08 декабря 2010

Вам необходимо связать (сопоставить) строки во вставленных и удаленных столбцах.Нечто подобное должно работать лучше.

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)
...