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