SQLServer更新语句对空值扼流,即使使用isNull()

时间:2013-07-22 13:12:23

标签: sql sql-server isnull

请注意,我已经更改了表格和字段的名称,以使其简短易懂。

我有一个问题归结为:

update destTable 
set destField = ( select top 1 isnull(s.sourceField, '') from sourceTable s 
where <various matches between the destTable table and the s table>
);

(我知道语法'更新destTable设置destField ...来自destTable d,sourceTable s ...',但我不知道如何将“top 1”放入其中。)

从中我得到SQLServer 2012 Express结果:

Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'destField', table 'destTable'; column does not allow nulls. UPDATE fails.
The statement has been terminated.

对于这两个表,所有字段都定义为not-null和default('')。

“top 1”很重要,因为sourceTable可能有多个匹配“where”子句。

我查询了sourceTable的所有行,发现它的所有sourceField值都是非null。然而,我得到了结果。

查询的性质是,在1000个destTable记录中,与sourceTable的匹配将仅产生300行的匹配。其他700个destTable记录将没有匹配。

我不明白SQLServer对我做了什么。当我上次使用MySQL运行它时,此查询工作正常。

提前致谢, 杰罗姆。

1 个答案:

答案 0 :(得分:7)

问题是查询没有返回任何行。 。 。因此产生一个NULL值。将isNULL()移到子查询之外:

update destTable 
set destField =  isnull((select top 1 s.sourceField
                         from sourceTable s 
                         where <various matches between the destTable table and the s table>
                        ), '');

顺便说一句,通常我会在这种情况下提倡coalesce(),因为它是标准。然而,正如Aaron Bertrand here所描述的那样,两者表现不同。特别是,第一个参数似乎被评估了两次,当它是一个子查询时非常昂贵。 Isnull()显然没有这个问题。