即使使用 isNull(),SQLServer 更新语句也会因空值而阻塞

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

(我知道语法“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/

相关文章:

sql - 带有 many-ISNULL 的多列 UPDATE-JOIN 需要很长时间?

Java 8 中的 java.sql.Date 与 Java 6 的比较

java - JDBC 连接到 Azure 中的 Java 数据库

sql-server - 作业数据库和目标数据库是否需要位于不同的服务器上?

asp.net - Multi-Tenancy 或非 Multi-Tenancy

mysql - 如果具有空值,如何编写子查询别名的条件

javascript - SSRS : Action "Go to URL" not working after applied to data cell in matrix

php - SQL选择计数代码不起作用

MySQL 优化器 - 成本规划器不知道 DuplicateWeedout 策略何时创建磁盘表

sql-server - SQL 中的 ISNULL 和隐式数据类型转换