4

昨天在 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 编译来解释这一点?

4

2 回答 2

3

It's down to Data Type Precedence, as detailed in the documentation

[CASE] Returns the highest precedence type from the set of types in result_expressions and the optional else_result_expression.

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

You can break it entirely by adding the line

WHEN 1 = 3 then getdate()

There's a more detailed explanation here

I imagine that the compiler assumes that all cases may be possible (your example is of course deliberately perverse :) )

于 2012-10-18T08:39:21.563 回答
0

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

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

CASE 
    WHEN 1 > 2 
        THEN @a / 100

使case结果为@a, a的类型real。将其更改为:

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

得到结果为decimal(18,10).

于 2012-10-18T08:34:04.900 回答