#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. Тогда все должно быть в порядке. Я также добавил раннее спасение для нулевых вставок строк, которое также лучше иметь, поскольку оно предотвращает запуск остальной части триггера вообще, избегая затрат на компиляцию и блокировку.