如何在下面的代码中将合并查询替换为SQL Server 2005中的其他代码 获得相同的功能。
alter trigger [Emp_Update_Logging] on [Employee_Test]
after update
as
MERGE INTO dbo.Emp_Log EL
USING INSERTED I
ON EL.EID = I.Emp_ID
WHEN MATCHED THEN
UPDATE
SET EL.ModifiedDate = getdate()
WHEN NOT MATCHED THEN
INSERT(EID,ModifiedDate)
VALUES(I.Emp_ID,getdate());
go
答案 0 :(得分:2)
您基本上需要将MERGE
分解为两个操作 - 对于那些尚不存在的行INSERT
,对那些已存在的行UPDATE
。ALTER TRIGGER [Emp_Update_Logging] ON [Employee_Test]
AFTER UPDATE
AS
-- insert those rows from Inserted that don't exist yet
INSERT INTO dbo.Emp_Log(EID, ModifiedDate)
SELECT I.Emp_ID, GETDATE()
FROM Inserted i
WHERE NOT EXISTS (SELECT * FROM dbo.Emp_Log WHERE EID = i.Emp_ID)
-- update those rows that already exist
UPDATE dbo.Emp_Log
SET ModifiedDate = GETDATE()
FROM Inserted i
WHERE EXIST (SELECT * FROM dbo.Emp_Log WHERE EID = i.Emp_ID)
。
这样的事可能有用:
{{1}}
但是,由于这是一个 UPDATE 触发器,我认为你永远不会有不存在的行 - 毕竟,这个触发器只在一个EXISTING行是更新 .....
答案 1 :(得分:0)
我认为您想先做UPDATE
,然后再做INSERT
。
对于用其他一些SQL代码替换Merge
的通用解决方案,Marc的答案看起来并非100%正确。
在他的具体答案中,这没有什么害处,因为对于insert
和update
而言,该示例只是将时间戳更新到现在。但是,如果根据数据是Insert
还是Update
对数据进行了不同的处理,则无法使用此格式。在此答案中,Insert
添加了丢失的行...但是Update
将更新所有行,而不仅仅是以前存在的旧行。
步骤1中新插入的行现在成为步骤2中Where Exists
子句的一部分。
我刚刚在此答案中提出的问题的简单解决方案是先执行UPDATE
,然后再进行INSERT
。
ALTER TRIGGER [Emp_Update_Logging] ON [Employee_Test]
AFTER UPDATE
AS
-- update those rows that already exist
UPDATE dbo.Emp_Log
SET ModifiedDate = GETDATE()
FROM Inserted i
WHERE EXIST (SELECT * FROM dbo.Emp_Log WHERE EID = i.Emp_ID)
-- insert those rows from Inserted that don't exist yet
INSERT INTO dbo.Emp_Log(EID, ModifiedDate)
SELECT I.Emp_ID, GETDATE()
FROM Inserted i
WHERE NOT EXISTS (SELECT * FROM dbo.Emp_Log WHERE EID = i.Emp_ID)
而且...我不是Where EXIST / NOT EXIST
条款的忠实拥护者。在某些情况下,最好将left join
与dbo.Emp_Log
并添加到您的where
子句中以检查值是否为NULL
。