SQL Server中的一个奇怪的操作问题(-100 / -100 * 10 = 0)

时间:2019-02-04 09:43:08

标签: sql sql-server tsql operator-precedence

  • 如果执行SELECT -100/-100*10,则结果为0
  • 如果执行SELECT (-100/-100)*10,则结果为10
  • 如果执行SELECT -100/(-100*10),则结果为0
  • 如果执行SELECT 100/100*10,则结果为10

BOL状态:

  

当表达式中的两个运算符具有相同的运算符优先级时,将根据它们在表达式中的位置从左到右进行求值。

Level   Operators
  1     ~ (Bitwise NOT)
  2     * (Multiplication), / (Division), % (Modulus)
  3     + (Positive), - (Negative), + (Addition), + (Concatenation), - (Subtraction), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR)

BOL是错了,还是我错过了什么?似乎-放弃了(预期的)优先级。

3 个答案:

答案 0 :(得分:85)

根据优先级表,此 是预期的行为。优先级较高的运算符(/*在优先级较低的运算符(一元-之前)被评估。所以这个:

-100 / -100 * 10

评估为:

-(100 / -(100 * 10))

请注意,此行为与大多数编程语言不同,在大多数编程语言中,一元求反的优先级比乘法和除法的优先级高。 VBJavaScript

答案 1 :(得分:30)

BOL是正确的。 -的优先级低于*,因此

-A * B

解析为

-(A * B)

乘法就是它,除了在其他两个具有相同优先级的二进制运算符:/%中混合使用(而%很少在这样的复合表达式中使用)。所以

C / -A * B

解析为

C / -(A * B)

解释结果。这是违反直觉的,因为在大多数其他语言中,一元减号的优先级高于*/,但在T-SQL中则没有,并且已被正确记录。

一种很好的(?)说明方式:

SELECT -1073741824 * 2

产生算术溢出,因为-(1073741824 * 2)产生2147483648作为中间体,但不适合INT,但

SELECT (-1073741824) * 2

产生预期的结果-2147483648

答案 2 :(得分:10)

文档中的通知({可能是反直觉的)- (Negative)的优先级为第三。

因此您可以有效地获得:

-(100/-(100*10)) = 0

如果将它们放入变量中,您将不会看到这种情况,因为乘法之后不会发生一元运算。

因此,这里的A和B相同,而C,D,E显示的是您看到的结果(E带有完整的包围)

DECLARE @i1 int, @i2 int, @i3 int;

SELECT @i1 = -100,
       @i2 = -100,
       @i3 = 10;

SELECT @i1/@i2*@i3      [A],
       -100/(-100)*10   [B],
       -100/-100*10     [C],
       -100/-(100*10)   [D],
       -(100/-(100*10)) [E];

A - 10
B - 10
C - 0
D - 0
E - 0