请注意,我更改了表和字段的名称,以使内容简短易懂。
我有一个疑问,归结为:
update destTable
set destField = ( select top 1 isnull(s.sourceField, '') from sourceTable s
where <various matches between the destTable table and the s table>
);
(我知道语法“update destTable set destField ... from 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.
对于这两个表,所有字段都定义为非空和默认值 ('')。
“top 1”很重要,因为 sourceTable 可能有多个“where”子句匹配项。
我查询了sourceTable的所有行,发现它的所有sourceField值都是非空的。但我得到了结果。
查询的本质是,在大约 1000 个 destTable 记录中,与 sourceTable 的匹配将仅产生 300 行的匹配。其他 700 条 destTable 记录不会匹配。
我不明白 SQLServer 对我做了什么。当我上次使用 MySQL 运行该查询时,它运行得很好。
提前致谢, 杰罗姆。
最佳答案
问题是查询没有返回任何行。 。 。因此产生一个 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()
显然,不存在这个问题。
关于即使使用 isNull(),SQLServer 更新语句也会因空值而阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17788530/