"INSTEAD OF UPDATE " 触发器内部的 MSSQL 条件检查
MSSQL conditional check inside of "INSTEAD OF UPDATE " trigger
使用 MSSQL2008。
我有两个table。
TableResource
-------------
ID [bigint]
Attribute1 [int]
Attribute2 [int]
Attribute3 [int]
VersionId [uniqueidentifier]
和
TableResourceHistory
--------------------
ID [bigint]
Attribute3History [int]
HistoryDate [datetime]
VersionId [uniqueidentifier]
我有一个 instead of update
触发器需要完成两件事:
- 如果字段“
TableReResource.Attribute3
”已更改,则使用 "old" Attribute3 值将历史记录写入历史记录 table 并且还修改“TableResource.VersionId
" TableResource
table. 的字段
- 如果“
TableReResource.Attribute3
”没有变化,则直接通过更新。
这是我目前所知道的,但是我在想出触发历史日志的相等比较时遇到了问题。
CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId] ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
SET NOCOUNT ON;
BEGIN
-- ?? IF inserted.Attribute3 = deleted.Attribute3
-- ?? THEN we just pass the UPDATE through
UPDATE [TableResources]
SET
VersionId = inserted.VersionId,
Attribute1 = inserted.Attribute1,
Attribute2 = inserted.Attribute2
FROM Inserted, TableResources
WHERE Inserted.ID = TableResources.ID
-- ??? ELSE, the Attribute3 field was updated, and we perform the history log
-- ??? and give it a new version number
-- History Log
INSERT TableResourceHistory (Attribute3History, HistoryDate, VersionId)
SELECT NEWID(), GETUTCDATE(), deleted.VersionId
FROM deleted
-- pass through the update, but assign a new VersionId
UPDATE [TableResources]
SET
VersionId = NEWID(),
Attribute1 = inserted.Attribute1,
Attribute2 = inserted.Attribute2
FROM Inserted, TableResources
WHERE Inserted.ID = TableResources.ID
END
有什么想法吗? TIA!
历史 table 插入只有在 Attribute3
发生变化时才会发生。
试试这个
CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId]
ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
SET NOCOUNT ON;
BEGIN
IF EXISTS(SELECT 1
FROM inserted i
JOIN deleted d
ON i.ID = d.ID
AND i.Attribute3 = d.Attribute3)
BEGIN
UPDATE T
SET VersionId = inserted.VersionId,
Attribute1 = inserted.Attribute1,
Attribute2 = inserted.Attribute2
FROM Inserted I
JOIN [TableResources] T
ON I.ID = T.ID
JOIN deleted d
ON i.ID = d.ID
AND i.Attribute3 = d.Attribute3
END
IF EXISTS(SELECT 1
FROM inserted i
JOIN deleted d
ON i.ID = d.ID
AND i.Attribute3 <> d.Attribute3)
BEGIN
INSERT TableResourceHistory
(Attribute3History,HistoryDate,VersionId)
SELECT Newid(),
Getutcdate(),
d.VersionId
FROM deleted d
JOIN Inserted i
ON i.ID = d.ID
AND i.Attribute3 <> d.Attribute3
-- pass through the update, but assign a new VersionId
UPDATE T
SET VersionId = Newid(),
Attribute1 = inserted.Attribute1,
Attribute2 = inserted.Attribute2
FROM Inserted I
JOIN [TableResources] T
ON I.ID = T.ID
JOIN deleted d
ON i.ID = d.ID
AND i.Attribute3 <> d.Attribute3
END
END
如果出现问题或未按预期工作,请在此答案下方的评论部分回复
我会这样做
拳头插入历史然后更新
我看不到你的属性 3 的任何更新,但我确实把它放在了我的触发器中
此外,历史日志中的 ID 似乎是唯一的 link 连接表,所以我猜它不是历史表中的主键
CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId] ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
SET NOCOUNT ON;
BEGIN
-- History Log, insert the old Attribute3 value (If in the Set values)
IF UPDATE(Attribute3)
BEGIN
INSERT TableResourceHistory (ID, HistoryDate, Attribute3History, VersionId)
Select i.ID, GETUTCDATE(), d.Attribute3, d.versionId
FROM inserted i
INNER JOIN deleted d on i.ID = d.ID
WHERE i.Attribute3 <> d.Attribute3
END
-- Update the table Use NewID() when Attribute3 differs
UPDATE T SET
VersionId = Case when UPPDATE(Attribute3) AND i.Attribute3 <> d.Attribute3 then NewID() ELSE i.VersionId END,
Attribute1 = i.Attribute1,
Attribute2 = i.Attribute2,
Attribute3 = i.Attribute3
FROM [TableResources] T
INNER JOIN inserted i on i.ID = T.ID
INNER JOIN deleted d on d.ID = i.ID
END
编辑:
Chris 让我知道了 UPDATE(Field) 函数。
最好的问候 Lars Skogshus
与 Chris Chilvers
互补
使用 MSSQL2008。
我有两个table。
TableResource
-------------
ID [bigint]
Attribute1 [int]
Attribute2 [int]
Attribute3 [int]
VersionId [uniqueidentifier]
和
TableResourceHistory
--------------------
ID [bigint]
Attribute3History [int]
HistoryDate [datetime]
VersionId [uniqueidentifier]
我有一个 instead of update
触发器需要完成两件事:
- 如果字段“
TableReResource.Attribute3
”已更改,则使用 "old" Attribute3 值将历史记录写入历史记录 table 并且还修改“TableResource.VersionId
"TableResource
table. 的字段
- 如果“
TableReResource.Attribute3
”没有变化,则直接通过更新。
这是我目前所知道的,但是我在想出触发历史日志的相等比较时遇到了问题。
CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId] ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
SET NOCOUNT ON;
BEGIN
-- ?? IF inserted.Attribute3 = deleted.Attribute3
-- ?? THEN we just pass the UPDATE through
UPDATE [TableResources]
SET
VersionId = inserted.VersionId,
Attribute1 = inserted.Attribute1,
Attribute2 = inserted.Attribute2
FROM Inserted, TableResources
WHERE Inserted.ID = TableResources.ID
-- ??? ELSE, the Attribute3 field was updated, and we perform the history log
-- ??? and give it a new version number
-- History Log
INSERT TableResourceHistory (Attribute3History, HistoryDate, VersionId)
SELECT NEWID(), GETUTCDATE(), deleted.VersionId
FROM deleted
-- pass through the update, but assign a new VersionId
UPDATE [TableResources]
SET
VersionId = NEWID(),
Attribute1 = inserted.Attribute1,
Attribute2 = inserted.Attribute2
FROM Inserted, TableResources
WHERE Inserted.ID = TableResources.ID
END
有什么想法吗? TIA!
历史 table 插入只有在 Attribute3
发生变化时才会发生。
试试这个
CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId]
ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
SET NOCOUNT ON;
BEGIN
IF EXISTS(SELECT 1
FROM inserted i
JOIN deleted d
ON i.ID = d.ID
AND i.Attribute3 = d.Attribute3)
BEGIN
UPDATE T
SET VersionId = inserted.VersionId,
Attribute1 = inserted.Attribute1,
Attribute2 = inserted.Attribute2
FROM Inserted I
JOIN [TableResources] T
ON I.ID = T.ID
JOIN deleted d
ON i.ID = d.ID
AND i.Attribute3 = d.Attribute3
END
IF EXISTS(SELECT 1
FROM inserted i
JOIN deleted d
ON i.ID = d.ID
AND i.Attribute3 <> d.Attribute3)
BEGIN
INSERT TableResourceHistory
(Attribute3History,HistoryDate,VersionId)
SELECT Newid(),
Getutcdate(),
d.VersionId
FROM deleted d
JOIN Inserted i
ON i.ID = d.ID
AND i.Attribute3 <> d.Attribute3
-- pass through the update, but assign a new VersionId
UPDATE T
SET VersionId = Newid(),
Attribute1 = inserted.Attribute1,
Attribute2 = inserted.Attribute2
FROM Inserted I
JOIN [TableResources] T
ON I.ID = T.ID
JOIN deleted d
ON i.ID = d.ID
AND i.Attribute3 <> d.Attribute3
END
END
如果出现问题或未按预期工作,请在此答案下方的评论部分回复
我会这样做 拳头插入历史然后更新 我看不到你的属性 3 的任何更新,但我确实把它放在了我的触发器中 此外,历史日志中的 ID 似乎是唯一的 link 连接表,所以我猜它不是历史表中的主键
CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId] ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
SET NOCOUNT ON;
BEGIN
-- History Log, insert the old Attribute3 value (If in the Set values)
IF UPDATE(Attribute3)
BEGIN
INSERT TableResourceHistory (ID, HistoryDate, Attribute3History, VersionId)
Select i.ID, GETUTCDATE(), d.Attribute3, d.versionId
FROM inserted i
INNER JOIN deleted d on i.ID = d.ID
WHERE i.Attribute3 <> d.Attribute3
END
-- Update the table Use NewID() when Attribute3 differs
UPDATE T SET
VersionId = Case when UPPDATE(Attribute3) AND i.Attribute3 <> d.Attribute3 then NewID() ELSE i.VersionId END,
Attribute1 = i.Attribute1,
Attribute2 = i.Attribute2,
Attribute3 = i.Attribute3
FROM [TableResources] T
INNER JOIN inserted i on i.ID = T.ID
INNER JOIN deleted d on d.ID = i.ID
END
编辑: Chris 让我知道了 UPDATE(Field) 函数。
最好的问候 Lars Skogshus
与 Chris Chilvers