【问题标题】:SQL MERGE INTO - How to delete then insert matched/existing data?SQL MERGE INTO - 如何删除然后插入匹配/现有的数据?
【发布时间】:2016-03-28 18:40:19
【问题描述】:

我目前有一个存储过程,它将我的目标表 (Ticket_Report) 与我的数据源表 (New_Tickets) 进行比较。

我正在使用 MERGE INTO 语句来比较这两者。当它在两个表之间找到匹配项时,它会使用源表中的相应信息更新目标表中的当前行。如果它没有找到匹配项,它会将源表中的数据插入到目标表中。

 MERGE INTO Ticket_REPORT T1
  USING @New_Tickets T2
  ON T1.TICKET_NO=T2.TICKET_NO
  WHEN MATCHED THEN
  UPDATE SET 
      T1.TICKET_NO = T2.TICKET_NO, 
      T1.ASSIGNED_GROUP = T2.ASSIGNED_GROUP, 
      T1.ASSIGNEE = T2.ASSIGNEE, 
      T1.FNAME = T2.FNAME, 
      T1.LNAME = T2.LNAME
WHEN NOT MATCHED THEN
  INSERT VALUES(
      T2.TICKET_NO, 
      T2.ASSIGNED_GROUP, 
      T2.ASSIGNEE, 
      T2.FNAME, 
      T2.LNAME
 );

我需要做的是,当我找到 MATCH 时,我需要删除该行,而不是仅仅更新该行,并将其重新插入到目标表中。谁能告诉我如何在找到 MATCH 时一个接一个地删除和插入?

【问题讨论】:

    标签: sql-server tsql stored-procedures merge


    【解决方案1】:

    这是一个例子:

    DECLARE @t1 TABLE(id INT IDENTITY, col1 INT)
    DECLARE @t2 TABLE(id INT IDENTITY, col1 INT, old_col1 INT)
    
    INSERT INTO @t1(col1) VALUES(5), (10), (15)
    INSERT INTO @t2(col1) VALUES(7), (14), (21), (28)
    
    MERGE INTO @t2 t2
    USING @t1 t1 ON t1.id = t2.id
    WHEN MATCHED THEN DELETE
    WHEN NOT MATCHED THEN INSERT VALUES(t1.col1, NULL)
    OUTPUT t1.col1, Deleted.col1 INTO @t2(col1, old_col1);
    
    SELECT * FROM @t2
    ORDER BY id
    

    输出:

    id  col1  old_col1
    4   28    NULL
    5   5     7
    6   10    14
    7   15    21
    

    前 3 行两者的 id 相同,因此匹配部分将删除那些(7、14、21)。将保留 28 个。然后在OUTPUT 子句中插入新值并保留旧值。

    【讨论】:

    • 我能否在 OUTPUT 中捕获已删除的行,然后 INTO 用作插入语句?
    • @Reeggiie,是的。该示例演示了这一点。
    【解决方案2】:

    @Giorgi,这并不完全有效。 如果@t1 的行数比@t2 多,就会出现重复。

    DECLARE @t1 TABLE(id INT IDENTITY, col1 INT)
    DECLARE @t2 TABLE(id INT IDENTITY, col1 INT, old_col1 INT)
    
    INSERT INTO @t1(col1) VALUES(5), (10), (15), (20), (25)
    INSERT INTO @t2(col1) VALUES(7), (14), (21), (28)
    
    MERGE INTO @t2 t2
    USING @t1 t1 ON t1.id = t2.id
    WHEN MATCHED THEN DELETE
    WHEN NOT MATCHED THEN INSERT VALUES(t1.col1, NULL)
    OUTPUT t1.col1, Deleted.col1 INTO @t2(col1, old_col1);
    
    SELECT * FROM @t2
    ORDER BY id
    
    id   col1  old_col1
    5    25    NULL
    6    25    NULL
    7    5     7
    8    10    14
    9    15    21
    10   20    28
    

    【讨论】:

      【解决方案3】:

      最简单的方法是运行2次

      DECLARE @t1 TABLE(id INT IDENTITY, col1 INT)
      DECLARE @t2 TABLE(id INT IDENTITY, col1 INT, old_col1 INT)
      
      INSERT INTO @t1(col1) VALUES(5), (10), (15), (20), (25)
      INSERT INTO @t2(col1) VALUES(7), (14), (21), (28)
      

      -- 首次运行;

      MERGE INTO @t2 t2
      USING @t1 t1 ON t1.id = t2.id
      WHEN MATCHED THEN DELETE
      

      --第二次运行;

      MERGE INTO @t2 t2
      USING @t1 t1 ON t1.id = t2.id
      WHEN NOT MATCHED THEN INSERT VALUES(t1.col1, NULL)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-26
        • 2012-12-05
        • 1970-01-01
        • 2019-01-12
        • 1970-01-01
        相关资源
        最近更新 更多