MERGE也插入NULL记录

时间:2016-06-12 10:10:43

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

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

  

无法将值NULL插入“Name”列,表'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);

2 个答案:

答案 0 :(得分:3)

ON子句只是确定了确定"匹配"的标准。是什么分支。它不是过滤器。

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

可以将这些附加谓词添加到各个分支。 E.g。

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); 

答案 1 :(得分:0)

您只需在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);