如何用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
您基本上需要将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)
但是,由于这是 update 触发器,我认为您永远不会有不存在的行 - 毕竟,这仅在现有行是时才触发更新 .....
我想您想先执行UPDATE
,然后进行INSERT
。
对于使用其他一些SQL代码替换Merge
的一般通用解决方案,MARC的答案看起来不正确。
在他的具体答案中,没有任何伤害,因为对于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
子记录的忠实拥护者。在某些情况下,使用dbo.Emp_Log
对left join
将是有益的,并添加到您的where
子句中检查是否为NULL
。