【问题标题】:Replacing Merge in SQL Server with some other code用其他代码替换 SQL Server 中的 Merge
【发布时间】:2014-02-10 14:40:38
【问题描述】:

如何在下面的代码中用 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

【问题讨论】:

    标签: sql-server merge


    【解决方案1】:

    您基本上需要将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 触发器,我认为您永远不会有尚不存在的行 - 毕竟,此触发器仅在 EXISTING 行是更新了 .....

    【讨论】:

    • 如果没有我自己的例子,这种格式看起来并不是 100% 正确的。在这种特定情况下,没有什么坏处,因为对于insertupdate,该示例只是将时间戳更新到现在。但是,如果根据数据是Insert 还是Update 对数据进行了不同的处理,我们就不能使用这种格式。在这个答案中,Insert 添加了缺失的行......但Update 将更新所有行,而不仅仅是以前存在的旧行。步骤 1 中新插入的行现在是步骤 2 中 Where exists 子句的一部分。
    • 您不一定可以使用这是一个Update 触发器这一事实来消除Update 语句。触发器在table [Employee_Test],但代码正在更新或插入到table dbo.Emp_Log
    【解决方案2】:

    我认为您想先执行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 会很有用。

    【讨论】:

      猜你喜欢
      • 2015-05-09
      • 2012-05-18
      • 1970-01-01
      • 2021-02-13
      • 2012-01-09
      • 2014-09-16
      • 2015-09-10
      • 1970-01-01
      • 2011-07-07
      相关资源
      最近更新 更多