【问题标题】:ISNULL and Implicit datatype conversions in TSQLSQL 中的 ISNULL 和隐式数据类型转换
【发布时间】:2016-04-10 12:01:59
【问题描述】:

在使用 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。为什么?

【问题讨论】:

    标签: sql-server tsql type-conversion isnull


    【解决方案1】:

    这里ISNULL('', 0) 返回''ISNULL(NULL, 0) 返回0

    Data Type Precedence ...

    当运算符组合不同数据类型的两个表达式时, 数据类型优先级规则指定具有 较低优先级转换为具有较高优先级的数据类型 优先级。如果转换不是受支持的隐式转换, 返回错误。

    由于intchar 拥有更多Precedence'' 将转换为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 ...

    返回与 check_expression 相同的类型。如果文字 NULL 是 作为 check_expression 提供,返回的数据类型 替换值。如果提供文字 NULL 作为 check_expression 并且没有提供 replacement_value,返回一个 int

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

    所以

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

    因此打印false

    【讨论】:

    • 很好解释。竖起大拇指!
    • 我没有遇到 ISNULL 转换行为的解释,这当然是解释 - 零作为替换值被转换为“0”。这就回答了这个问题。谢谢,普拉文。
    • 让我发布这个问题的原因是,在 ISNULL 表达式中的检查表达式和替换值之间没有遵循关于数据类型优先级的一般规则。我对此有一个错误的假设。实际上,检查表达式的类型始终具有优先权(我现在很清楚)。
    【解决方案2】:

    试试这个:

    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 的几种用法,这让我对这里发生的事情有了全面而深入的了解。所以除了理解别人写的代码,我什么也做不了。
    猜你喜欢
    • 1970-01-01
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多