为什么我的动态查询 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 中找到
因为
您的 table 中有一行 ColumnValue
包含文字字符串 'NUL'
动态查询生成的第一行不超过 3 个字符宽,因此引擎推断它应该输出 varchar(3)
列。然后 'NULL'
被截断为 'NUL'
特别是,如果查询的第一行 ColumnValue
为空,则表达式 ISNULL(''''+ NULL+'''', 'NULL')
的类型被评估为 ''''+ NULL+''''
[=19 的类型=]
第二种情况你应该可以通过类似
的方法来解决
Concat ('(', ISNULL(Cast(''''+ Null +'''' as VarChar(4)), 'NULL'), ')' )
您通常更喜欢 COALESCE
而不是 ISNULL
1.
的众多原因之一
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 的定义中,其中数据库引擎用于分析ISNULL
和 COALESCE
不同,我希望它计算结果数据类型是 not null
。不确定这种差异是否仍然存在。
在动态 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 中找到
因为
您的 table 中有一行
ColumnValue
包含文字字符串'NUL'
动态查询生成的第一行不超过 3 个字符宽,因此引擎推断它应该输出
varchar(3)
列。然后'NULL'
被截断为'NUL'
特别是,如果查询的第一行 ColumnValue
为空,则表达式 ISNULL(''''+ NULL+'''', 'NULL')
的类型被评估为 ''''+ NULL+''''
[=19 的类型=]
第二种情况你应该可以通过类似
的方法来解决Concat ('(', ISNULL(Cast(''''+ Null +'''' as VarChar(4)), 'NULL'), ')' )
您通常更喜欢 COALESCE
而不是 ISNULL
1.
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 的定义中,其中数据库引擎用于分析ISNULL
和 COALESCE
不同,我希望它计算结果数据类型是 not null
。不确定这种差异是否仍然存在。