SQL REAL 0部门在SQL Server 2008上引起了有趣的错误

时间:2012-10-18 08:23:47

标签: sql-server sql-server-2008 compilation real-datatype

昨天在SQL Server上发现了一个有趣的问题,试试这个:

DECLARE @a REAL = 0.0000
DECLARE @c DECIMAL (18,10) = 20754/3.45 -- this is 6015.6521730000
DECLARE @b DECIMAL (18,10) = 
CASE 
    WHEN 1 > 2 
        THEN @a / 100
    WHEN 1 = 2
        THEN 56
    ELSE @c
END

SELECT @b

这似乎是精度问题,以及如何编译case语句。通过在case语句中将REAL @a转换为小数可以很容易地解决这个问题,但是因为它是@c我们正在返回而其他情况永远不会被击中,这是一个奇怪的问题。 有人对SQL编译有足够的了解吗?

2 个答案:

答案 0 :(得分:3)

它低至Data Type Precedence,详见文档

  

[CASE]从result_expressions中的类型集和可选的else_result_expression返回最高优先级类型。

http://msdn.microsoft.com/en-us/library/ms181765(v=sql.100).aspx

您可以通过添加行

来完全破坏它
WHEN 1 = 3 then getdate()

有一个更详细的解释here

我想编译器假设所有情况都是可能的(你的例子当然是刻意反常:))

答案 1 :(得分:0)

这是一个错误的答案,请参阅podiluska对正确答案的回答。

case语句的结果类型是第一个then子句的类型。所以:

CASE 
    WHEN 1 > 2 
        THEN @a / 100

使case结果的类型为@areal。将其更改为:

CASE 
    WHEN 1 > 2 
        THEN cast(@a as decima(18,10)) / 100

将结果设为decimal(18,10)