用其他一些代码替换SQL Server中的Merge

时间:2014-01-21 06:27:38

标签: sql-server merge

如何在下面的代码中将合并查询替换为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

2 个答案:

答案 0 :(得分:2)

您基本上需要将MERGE分解为两个操作 - 对于那些尚不存在的行INSERT,对那些已存在的行UPDATEALTER 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%正确。

在他的具体答案中,这没有什么害处,因为对于insertupdate而言,该示例只是将时间戳更新到现在。但是,如果根据数据是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 joindbo.Emp_Log并添加到您的where子句中以检查值是否为NULL