【问题标题】:Arithmetic overflow error for data type tinyint, value = -1数据类型 tinyint 的算术溢出错误,值 = -1
【发布时间】:2014-06-11 13:48:41
【问题描述】:

在运行此查询时,我收到错误,知道为什么吗?

select ISNULL(NULLIF(0,0), -1)

错误:

消息 220,第 16 级,状态 2,第 1 行

数据类型 tinyint 的算术溢出错误,值 = -1。

编辑——另一个例子:

select ISNULL(NULLIF(0.0,0.0), 1.0)

消息 8115,第 16 级,状态 8,第 1 行 将数值转换为数值数据类型时出现算术溢出错误。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    这项工作:

    select ISNULL(NULLIF(cast(0 as int),0), -1)
    

    SQL 优化器将“隐藏”强制转换为最小数据类型。

    来自 NULLIF (http://technet.microsoft.com/pl-pl/library/ms177562%28v=sql.110%29.aspx) 的文档:

    返回与第一个表达式相同的类型。

    所以 NULLIF 返回 tinyint 并且 ISNULL 尝试将 tinyint 替换为 -1 然后你有溢出

    当您将第一个参数 (0) 转换为 int(或 smallint)时,NULLIF 返回适合 -1 的“新”数据类型

    要查找正在使用的实际类型:

    SELECT NULLIF(0,0) test_col INTO #test_table
    
    SELECT data_type, numeric_precision, numeric_scale
    FROM tempdb.INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME LIKE '#test_table%' AND COLUMN_NAME = 'test_col'
    

    【讨论】:

      【解决方案2】:

      无论如何,这都是奇怪的行为。为什么像“0”这样的常量以不同的方式评估——有时是int,有时是tinyint。如果我选择一个常数“0”,那么它被评估为“int”。但是将“0”传递给 NULLIF() 常量被评估为 tinyint。 NULLIF 文档中根本没有提到这种行为。

      -- 1) SELECT evaluates numeric constant "0" as "int":
      DROP TABLE IF EXISTS #t
      GO
      SELECT c = 0
         INTO #t
      GO
      
      EXEC tempdb..sp_help #t
      GO
      
      -- 2) NULLIF() evaluates numeric constant "0" as "tynyint":
      DROP TABLE IF EXISTS #t
      GO
      SELECT c = NULLIF(0, 0)
         INTO #t
      GO
      
      EXEC tempdb..sp_help #t
      GO
      

      【讨论】:

        猜你喜欢
        • 2015-01-18
        • 2018-06-05
        • 1970-01-01
        • 2013-12-31
        • 1970-01-01
        • 2015-12-11
        • 1970-01-01
        • 2013-08-13
        • 1970-01-01
        相关资源
        最近更新 更多