表达式计算规则

子表达式的计算顺序是没有定义的。特别要指出的是, 一个操作符或者函数的输入并不一定是按照从左向右的顺序或者以某种特定的顺序进行计算的。

另外,如果一个表达式的结果可以通过只判断它的一部分就可以得到, 那么其它子表达式就可以完全不计算了。比如,如果我们这么写

SELECT true OR somefunc();

那么 somefunc() 就(可能)根本不会被调用。 如果我们写下面的,也可能会是这样

SELECT somefunc() OR true;

请注意这里和某些编程语言里的从左向右"短路"是不一样的。

因此,拿那些有副作用的函数作为复杂表达式的一部分是不明智的选择。 在 WHERE 和 HAVING 子句里面依赖副作用或者是计算顺序是特别危险的, 因为这些子句都是作为生成一个执行规划的一部分进行了大量的再处理。 在这些子句里的布尔表达式(AND/OR/NOT 的组合)可以以布尔代数运算律允许的任意方式进行识别。

如果强制计算顺序非常重要,那么可以使用 CASE 构造(参阅 Section 9.13)。 比如,下面是一种视图避免在 WHERE 子句里被零除的不可信的方法:

SELECT ... WHERE x <> 0 AND y/x > 1.5;

但是下面这样的是安全的:

SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;

用这种风格的 CASE 构造会阻止优化,因此应该只在必要的时候使用。 (在这个特殊的例子里,毫无疑问写成 y > 1.5*x 更好。)

你可能感兴趣的:(表达式计算规则)