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

ISNULL and Implicit datatype conversions in TSQL

我在使用 ISNULL 时遇到了一个有点奇怪的数据类型转换行为。看看这个:

PRINT CASE WHEN ISNULL('', 0) = 0 THEN 'true' ELSE 'false' END
PRINT CASE WHEN ISNULL('', 0) = '' THEN 'true' ELSE 'false' END
PRINT CASE WHEN ISNULL(NULL, 0) = '' THEN 'true' ELSE 'false' END

所有这些表达式的计算结果都为真。 但是当我声明一个 nvarchar 变量并将其设置为 NULL 时,会发生以下情况:

DECLARE @charType nvarchar; SET @charType = NULL;
PRINT CASE WHEN ISNULL(@charType, 0) = '' THEN 'true' ELSE 'false' END

这也应该评估为 true,但评估为 false。为什么?

试试这个:

PRINT CASE WHEN CAST(ISNULL('', 0) AS nvarchar) = 0 THEN 'true' ELSE 'false' END
PRINT CASE WHEN CAST(ISNULL('', 0) AS nvarchar) = '' THEN 'true' ELSE 'false' END
PRINT CASE WHEN CAST(ISNULL(NULL, 0) AS nvarchar) = '' THEN 'true' ELSE 'false' END

如您所见,当@charType 设置为 nvarchar 类型时,SQL 知道它需要转换为 nvarchar。

你想达到什么目的?

此处ISNULL('', 0)returns''ISNULL(NULL, 0)returns0

Data Type Precedence ...

When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence. If the conversion is not a supported implicit conversion, an error is returned.

由于 intPrecedence 多于 char'' 将转换为 int

select cast('' as int) ==> 0

因此在第一种情况下,所有 '' 都将转换为 0,因此查询将减少为

PRINT CASE WHEN 0 = 0 THEN 'true' ELSE 'false' END
PRINT CASE WHEN '' = '' THEN 'true' ELSE 'false' END
PRINT CASE WHEN 0 = 0 THEN 'true' ELSE 'false' END

因此它打印 true

ISNULL ...

Returns the same type as check_expression. If a literal NULL is provided as check_expression, returns the datatype of the replacement_value. If a literal NULL is provided as check_expression and no replacement_value is provided, returns an int

但在第二种情况下 @charTypenullISNULL 会将值 0 转换为 nvarchar 然后查询变为

所以

PRINT CASE WHEN '0' = '' THEN 'true' ELSE 'false' END

因此它打印 false