【问题标题】:T-SQL NULLIF returns NULL for zeroT-SQL NULLIF 返回 NULL 为零
【发布时间】:2018-05-25 22:45:48
【问题描述】:

为什么下面的脚本返回NULL 而不是0

DECLARE @number BIGINT = 0;

SELECT  NULLIF(@number, '');

根据 MSDN,它应该返回 0:

NULLIF
如果两个指定的表达式相等,则返回空值。

对于 SQL 服务器,0'' 是否被视为相同(=相等)?背后的逻辑是什么?

【问题讨论】:

标签: sql sql-server tsql sql-server-2017 nullif


【解决方案1】:

当一个操作符组合两个不同数据类型的表达式时,数据类型优先级规则规定将低优先级的数据类型转换为高优先级的数据类型。

SELECT CONVERT(bigint, '')
SELECT CONVERT(float, '')
SELECT CONVERT(date, '')

0
0
1900-01-01

https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-precedence-transact-sql

【讨论】:

    【解决方案2】:

    正如BOL 所说:“数据类型优先级规则指定将具有较低优先级的数据类型转换为具有较高优先级的数据类型。” 您有两种不同的数据类型,bigintnvarchar。为了比较两者,它们必须是相同的数据类型。按照所描述的规则,nvarchar 被隐式转换为bigint。试试select convert(bigint, ''),你会发现它的结果是0。所以它们是一样的。

    【讨论】:

      【解决方案3】:

      这个脚本应该返回 null 并且是真的! 它背后的原因是 '' 是一个字符串,所以当你现在将它与一个整数进行比较时,它会被隐式转换为一个整数值! 一般来说,当您比较不同数据类型的值时,您是在自找麻烦,因为隐式转换发生在幕后。

      【讨论】:

        【解决方案4】:

        这是隐式转换的结果。在某些情况下,可以将字符串值转换为整数(例如将空字符串转换为 0)。

        本质上,SQL Server 会先尝试匹配两个表达式的数据类型,然后再检查值。

        DECLARE @number BIGINT = 0;
        
        SELECT 
            CONVERT(BIGINT, '')
            , NULLIF(@number, '')
            , NULLIF(@number, CONVERT(BIGINT, ''))
        

        【讨论】:

          【解决方案5】:

          它已将'' 转换为整数0,因为整数在数据类型中具有更高的优先级。看看下面的例子''如何变成0

          SELECT CONVERT(INT, '')  -- 0
          SELECT CAST('' AS INT)   -- 0
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-02-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-16
            相关资源
            最近更新 更多