Триггер SQL Server для сохранения ревизий строк при ОБНОВЛЕНИИ и ВСТАВКЕ

#sql #sql-server #triggers

#sql #sql-server #триггеры

Вопрос:

У меня есть следующий триггер SQL Server, который я хочу выполнить следующим образом:

  • При включении INSERT сохраните новую строку в Documents ArchivedDocuments
  • Вкл UPDATE ., сохраните новую редакцию строки, если WordCount или PageCount или ContributorCount изменились по сравнению с текущими значениями с помощью UPDATE

Как мне этого добиться?

Мой текущий триггер просто сохраняет ArchivedDocument после каждого INSERT или UPDATE .

РЕДАКТИРОВАТЬ: Id является первичным ключом для таблицы документа. DocumentId является внешним ключом, на который ссылается Document.Id .

 CREATE TRIGGER [TRG__Documents] 
ON [Documents]
AFTER INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @now datetimeoffset = sysdatetimeoffset();

    INSERT INTO [DocumentRevisions] ([DocumentId], [Time], [WordCount], [PageCount], [ContributorCount])
        SELECT
            [inserted].[Id],
            @now,
            [inserted].[WordCount],
            [inserted].[PageCount],
            [inserted].[ContributorCount]
        FROM  
            [inserted]
END
 

Ответ №1:

Вам нужны EXCEPT любые совпадающие строки в deleted таблице. Я предполагаю Id , что это первичный ключ, если нет, то вам нужно будет изменить это, чтобы включить первичный ключ.

 create trigger [TRG__Documents] on [Documents]
    after insert, update
    as
    begin
        set nocount on;
        if(not exists (select 1 from inserted))
            return;

        declare @now datetimeoffset = sysdatetimeoffset();
        insert into [dbo].[DocumentRevisions] (
            [DocumentId],
            [Time],
            [WordCount],
            [PageCount],
            [ContributorCount]
        )
        select
            i.[Id],
            @now,
            i.[WordCount],
            i.[PageCount],
            i.[ContributorCount]
        from (
            select
                i.[Id],
                i.[WordCount],
                i.[PageCount],
                i.[ContributorCount]
            from inserted i
            except
            select
                d.[Id],
                d.[WordCount],
                d.[PageCount],
                d.[ContributorCount]
            from deleted d
        ) i
    end

 

Комментарии:

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