为什么我的动态查询在SQL Server中返回NUL而不是NULL?

时间:2018-11-02 10:56:03

标签: sql-server sql-server-2014

在动态SQL Server查询中,我想基于其他表构建动态插入脚本。

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

,并且如果原始表中的列值为空,我希望它返回NULL作为varchar值。 但是,当列值为空时: (基本上在SSMS中):select ISNULL(''''+ NULL+'''', 'NULL')然后返回的值是'NUL'varchar而不是NULL,而且我不知道为什么。 当我尝试查询超出动态上下文时,它会起作用:

select isnull(NULL,'NULL') 

这是功能还是错误?

编辑

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

2 个答案:

答案 0 :(得分:2)

COALESCE 1 相比,您通常更喜欢ISNULL的众多原因之一。

select COALESCE(''''+ NULL+'''', 'NULL')
如您所述,

NULL相同时返回ISNULL。返回NUL

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

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


1 我过去唯一使用ISNULL的地方是视图中计算列/表达式的定义,其中数据库引擎用来分析ISNULL和{ {1}}有所不同,我希望它计算得出的数据类型为COALESCE。不知道这种差异是否仍然存在。

答案 1 :(得分:1)

因为

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

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

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

的类型。

第二种情况,您应该可以通过类似的方式解决

Concat ('(', ISNULL(Cast(''''+ Null +'''' as VarChar(4)), 'NULL'), ')' )