【问题标题】:MERGE is inserting NULL records alsoMERGE 也在插入 NULL 记录
【发布时间】:2016-06-12 10:10:42
【问题描述】:

我正在使用以下语句来更新/插入记录。问题是我已经给出了条件SOURCE.Name IS NOT NULL,但我仍然在插入语句中收到错误消息:

无法将值 NULL 插入到列“名称”、表“TEST2”中;列不允许空值。更新失败。

那是因为在 TARGET 表的 Name 列上有一个 NOT NULL 约束。我只是不想插入任何包含 NULL 作为名称的记录。另外,我也不想更新 TAGRET 表中 Name 为 NULL 的任何行。

MERGE TEST2 AS TARGET       
USING TEST1 AS SOURCE    
ON TARGET.ID = SOURCE.ID
AND SOURCE.Name IS NOT NULL  
WHEN MATCHED THEN                           
    UPDATE SET ID=SOURCE.ID,
               Name= SOURCE.Name,
               City= SOURCE.City,
               State = SOURCE.State

WHEN NOT MATCHED THEN
INSERT (ID, Name, City, State)
VALUES(SOURCE.ID, SOURCE.Name, SOURCE.City, SOURCE.State);

【问题讨论】:

    标签: sql sql-server sql-server-2012


    【解决方案1】:

    ON 子句只是确定了确定“匹配”是什么以及采用什么分支的标准。它不是过滤器。

    如果ON 子句不匹配,那么您将转到WHEN NOT MATCHED 分支,因此在您的情况下,即使 id 匹配但源名称为空,这也将适用。

    可以将这些附加谓词添加到各个分支。例如

    WHEN NOT MATCHED AND SOURCE.Name IS NOT NULL 
    

    但由于您没有WHEN NOT MATCHED BY SOURCE 的分支,并且您拥有的两个分支都将排除 NULL,您不妨使用表表达式预先过滤掉所有这些。

    MERGE TEST2 AS TARGET
    USING (SELECT *
           FROM   TEST1
           WHERE  Name IS NOT NULL) AS SOURCE
    ON TARGET.ID = SOURCE.ID
    WHEN MATCHED THEN
      UPDATE SET ID = SOURCE.ID,
                 Name = SOURCE.Name,
                 City = SOURCE.City,
                 State = SOURCE.State
    WHEN NOT MATCHED THEN
      INSERT (ID,
              Name,
              City,
              State)
      VALUES(SOURCE.ID,
             SOURCE.Name,
             SOURCE.City,
             SOURCE.State); 
    

    【讨论】:

    • 感谢您的回复马丁。如果我不想更新 SOURCE 表中 Name 为 NULL 的记录,那么我还需要将相同的子句放在这里吗?当匹配且 SOURCE.Name 不为空时
    • @Newbie 我刚刚注意到了。您可以这样做,但请查看我的编辑以获得更好的方式。
    【解决方案2】:

    您只需要在 WHEN NOT MATCHED 中添加一个 AND 条件,如下所示:

    MERGE TEST2 AS TARGET       
    USING TEST1 AS SOURCE    
    ON TARGET.ID = SOURCE.ID
    AND SOURCE.Name IS NOT NULL  
    WHEN MATCHED THEN                           
        UPDATE SET ID=SOURCE.ID,
                   Name= SOURCE.Name,
                   City= SOURCE.City,
                   State = SOURCE.State
    
    WHEN NOT MATCHED AND SOURCE.Name IS NOT NULL THEN
    INSERT (ID, Name, City, State)
    VALUES(SOURCE.ID, SOURCE.Name, SOURCE.City, SOURCE.State);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-13
      相关资源
      最近更新 更多