T中数字类型的优先级

对于T-SQL处理CASE表达式中使用的各种numeric类型的方式,我完全是一棵树。 您可以使用以下测试来解释它吗?

-- Consider the query:
SELECT
CASE
        WHEN 1=1 THEN CAST(1.555 AS numeric(16,3))
        ELSE  CEILING((1+1) * CAST(1 AS Numeric(16,2)) * CAST(1 AS int))
END AS Test
-- This returns 2 (scale = 0)
-- Now, remove the CEILING function:
SELECT
CASE
        WHEN 1=1 THEN CAST(1.555 AS numeric(16,3))
        ELSE  (1+1) * CAST(1 AS Numeric(16,2)) * CAST(1 AS int)
END AS Test
-- and it gives 1.56 (scale = 2)
-- Now replace (1+1) with 2:
SELECT
CASE
        WHEN 1=1 THEN CAST(1.555 AS numeric(16,3))
        ELSE  (2) * CAST(1 AS Numeric(16,2)) * CAST(1 AS int)
END AS Test
-- and it yields 1.555 (scale = 3)

这似乎是错误的,因为在所有三个查询中, 1=1分支中的numeric(16,3)应该优先于ELSE分支的不太精确的结果。


问题在于,案例的第二个分支在每种情况下都有不同的数据类型。

SELECT CAST(1.555 AS NUMERIC(16, 3))                                   AS A,
       CEILING(( 1 + 1 ) * CAST(1 AS NUMERIC(16, 2)) * CAST(1 AS INT)) AS B,--NUMERIC(38,0)
       CAST(1.555 AS NUMERIC(16, 3))                                   AS C,
       ( 1 + 1 ) * CAST(1 AS NUMERIC(16, 2)) * CAST(1 AS INT)          AS D,--NUMERIC(38,2)
       CAST(1.555 AS NUMERIC(16, 3))                                   AS E,
       ( 2 ) * CAST(1 AS NUMERIC(16, 2)) * CAST(1 AS INT)              AS F --NUMERIC(29,2)
INTO   T

数字的最大比例是38

第一个有NUMERIC(38,0)的另一个分支NUMERIC(38,0)所以这也是返回类型。 如果else分支评估为99999999999999999999999999999999999999那么没有别的办法。

第二个有NUMERIC(38,2)的另一个分支NUMERIC(38,2)所以这也是类似原因的最后一个数据类型。 为了保留三位数的精度,它需要是NUMERIC(38,3)但是999999999999999999999999999999999999.99不适合。

第三个有NUMERIC(29,2)的另一个分支NUMERIC(29,2) 。 这不能达到最大38的比例,因此有扩大空间和保持比例的空间。 最终的返回类型是NUMERIC(30,3)

当然,这只是将问题稍微转移到为什么第二个分支全部评估不同。

在正常的事件过程中,以下表达式都计算为int (检查创建的表的定义)

SELECT ( 1 + 1 ) AS A,
       ( 2 )     AS B
INTO   T2 

所以这两者之间的不同行为没有明显的原因。 但我怀疑文字2被视为NUMERIC(1,0)通过检查实际值。

而稍微复杂的1 + 1表达式被视为任何未知的整数,并作为NUMERIC(10,0)

然后,您可以进入本页详细说明的规则,以便在乘法和除法数值时保持精度和比例。

链接地址: http://www.djcxy.com/p/81735.html

上一篇: Precedence of numeric types in T

下一篇: What is the use of http non persistent connection mode