Триггер ниже будет делать то, что вы хотите:
CREATE TRIGGER ItemTable_OnUpdate
ON ItemTable
INSTEAD OF UPDATE
AS
BEGIN
DECLARE @newId int, @oldId int
INSERT INTO ItemTable(Col, ColOther, Latest)
SELECT Col, ColOther, 1 FROM INSERTED
--get old and new ids
SELECT @newId=@@IDENTITY, @oldId=ID FROM INSERTED
UPDATE ItemTable SET Latest=0 WHERE ID=@oldId
--updating ProductTable
INSERT INTO ProductTable (ItemID, [Value], ValueOther, Latest)
SELECT @newId, [Value], ValueOther, 1 FROM ProductTable WHERE ItemID=@oldId
UPDATE ProductTable SET Latest=0 WHERE ItemID=@oldId
END;
После создания триггера любое обновление вставит новую запись в ItemTable
, обновите пред. с помощью Latest = 0
и обновите дочернюю таблицу согласно вашему требованию.
Ниже приведен мой вывод после обновления ниже:
UPDATE ItemTable SET col='new', ColOther='newother' WHERE ID=12;
ItemTable:
ID Col ColOther Latest Time
12 old oldother 0 0x00000000000007F0
13 new newother 1 0x00000000000007EF
ProductTable:
ID ItemID Value ValueOther Latest Time
18 12 foo bar 0 0x00000000000007F2
19 13 foo bar 1 0x00000000000007F1
Для обновлений с несколькими строками мы можем использовать приведенный ниже триггер, так как он был разработан как ссылка на обновление, указанное инициатором запроса (одна строка). Я считаю, что ниже будет обрабатывать несколько строк обновлений. пожалуйста, попробуйте.
create TRIGGER ItemTable_OnUpdate
ON ItemTable
INSTEAD OF UPDATE
AS
BEGIN
Declare @s table( IdNew int,IdOld int)
MERGE INTO ItemTable AS dest
USING INSERTED AS ins ON 1=0 -- always false
WHEN NOT MATCHED BY TARGET -- happens for every row, because 1 is never 0
THEN
INSERT (Col, ColOther, Latest)
VALUES (Col, ColOther, Latest)
OUTPUT inserted.ID, ins.ID INTO @s (IdNew, IdOld);
UPDATE ItemTable SET Latest=0 WHERE ID in (select IdOld from @s)
--updating ProductTable
INSERT INTO ProductTable (ItemID, [Value], ValueOther, Latest)
SELECT s.IdNew, pt.[Value], pt.ValueOther, 1 FROM @s s
inner join ProductTable pt on pt.ItemID=s.IdOld
UPDATE ProductTable SET Latest=0 WHERE ItemID in (select IdOld from @s)
END;