T-SQL中数值类型的优先级

Ant*_*222 7 sql t-sql sql-server

关于T-SQL句柄类型优先级与表达式中numeric使用的各种类型的方式,我完全是一棵树CASE.你能用以下测试解释一下吗:

-- 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)
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ith 4

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

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
Run Code Online (Sandbox Code Playgroud)

数字的最大刻度为38

第一个有一个 else 分支,NUMERIC(38,0)因此这也是返回类型。如果 else 分支的计算结果为 ,99999999999999999999999999999999999999那么其他分支都不起作用。

第二个有一个NUMERIC(38,2)so 的 else 分支,出于类似的原因,它也是最终的数据类型。为了保留三位数字的精度,它需要是NUMERIC(38,3),但这样999999999999999999999999999999999999.99就不适合了。

第三个有一个 else 分支NUMERIC(29,2)。这未达到最大 38 比例,因此还有稍微扩展并保留比例的空间。最终的返回类型是NUMERIC(30,3).

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

在正常情况下,以下表达式的计算结果均为int(检查创建的表的定义)

SELECT ( 1 + 1 ) AS A,
       ( 2 )     AS B
INTO   T2 
Run Code Online (Sandbox Code Playgroud)

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

而稍微复杂一点的1 + 1表达式则被视为任何未知整数,即 和NUMERIC(10,0)

然后,您将了解本页详细介绍的规则,以在数字相乘和除法时保留精度和小数位数。