为什么我的动态查询 returns NUL 而不是 SQL 服务器中的 NULL?

Why my dynamic query returns NUL instead of NULL in SQL server?

在动态 SQL 服务器查询中,我想构建一个基于其他 table 的动态插入脚本。

SELECT 'INSERT INTO MyTable(column) VALUES ' + Concat ('(',ISNULL(''''+ ColumnValue+'''', 'NULL'), ')' ) from myOriginalTable

如果原始 table 中的列值为 null,我希望它 return 'NULL' 作为 varchar 值。 但是当列值为空时: (基本上在 SSMS 中):select ISNULL(''''+ NULL+'''', 'NULL') 然后 returned 值是 'NUL' varchar 而不是 NULL,我不知道为什么。 当我尝试查询 outisde 动态上下文时,它起作用了:

select isnull(NULL,'NULL') 

这是功能还是错误?

编辑

这与 table 定义无关,要重现问题只需 运行 select ISNULL(''''+ NULL+'''', 'NULL') 在 SSMS 中或从在线平台 result 中找到

因为

  1. 您的 table 中有一行 ColumnValue 包含文字字符串 'NUL'

  2. 动态查询生成的第一行不超过 3 个字符宽,因此引擎推断它应该输出 varchar(3) 列。然后 'NULL' 被截断为 'NUL'

特别是,如果查询的第一行 ColumnValue 为空,则表达式 ISNULL(''''+ NULL+'''', 'NULL') 的类型被评估为 ''''+ NULL+''''[=19 的类型=]

第二种情况你应该可以通过类似

的方法来解决
Concat ('(', ISNULL(Cast(''''+ Null +'''' as VarChar(4)), 'NULL'), ')' )

您通常更喜欢 COALESCE 而不是 ISNULL1.

的众多原因之一
select COALESCE(''''+ NULL+'''', 'NULL')

returns NULL 当与 ISNULL 相同时,如您所述,returns NUL.

为什么?因为 ISNULL 没有使用 SQL Server 中其他地方使用的 data type precedence 的常规规则,而是强制结果具有与其第一个参数相同的数据类型,这对于上面显然是某种 [n][var]char(3) 类型。

另一方面,COALESCE 考虑其参数的 all 的类型(另一个喜欢它的原因 - 概括为两个以上的参数)来确定其结果的适当数据类型。由于 'NULL'char(4) 文字,因此生成的数据类型必须能够容纳至少 4 个字符。


1我曾经唯一使用 ISNULL 的地方是在视图中计算的 columns/expressions 的定义中,其中数据库引擎用于分析ISNULLCOALESCE 不同,我希望它计算结果数据类型是 not null。不确定这种差异是否仍然存在。