第一季度
这最终被添加到 Postgres 9.4的官方文档中:
一个 PL/pgSQL 变量的赋值写成:
variable { := | = } expression;
=
[...]可以使用Equal ( ) 代替 PL/SQL-compliant :=
。
第二季度
=
使用而不是有任何已知后果:=
吗?
是的,我遇到了一个后果严重的案例:使用命名参数的函数调用- 这是相关但不完全相同的事情。
严格来说,这种情况下的区别是在SQL代码中进行的。但这是对毫无戒心的程序员的学术差异。1
考虑函数:
CREATE FUNCTION f_oracle(is_true boolean = TRUE) -- correct use of "="
RETURNS text AS
$func$
SELECT CASE $1
WHEN TRUE THEN 'That''s true.'
WHEN FALSE THEN 'That''s false.'
ELSE 'How should I know?'
END
$func$ LANGUAGE sql;
另外:注意=
函数定义中的正确使用。这是CREATE FUNCTION
语法的一部分——以SQL赋值的方式。2
使用命名符号的函数调用:
SELECT * FROM f_oracle(is_true := TRUE);
Postgres 标识:=
为参数分配,一切都很好。但是:
SELECT * FROM f_oracle(is_true = TRUE);
由于=
是 SQL 相等运算符,Postgres 在调用语句的上下文中解释为 SQL 表达式,并在将结果作为未命名的位置参数is_true = TRUE
传递之前尝试对其进行评估。它在外部范围内查找标识符。如果找不到:is_true
ERROR: column "is_true" does not exist
这是幸运的情况,幸运的是,也是常见的情况。
Whenis_true
可以在外部范围内找到(并且数据类型兼容),is_true = TRUE
是一个有效的表达式,其boolean
结果被函数接受。不会发生错误。显然,这是程序员使用SQL相等运算符的意图=
......
这个SQL Fiddle演示了效果。
如果您不知道 和 之间的区别,则很难=
调试:=
。
始终使用正确的运算符。
1在函数调用中使用,只有:=
正确的赋值运算符。这适用于所有语言的函数,不仅仅是 PL/pgSQL,直到并包括 pg 9.4。见下文。
2
可以使用=
(或DEFAULT
)定义函数参数的默认值。这与手头的问题没有任何关系。它非常接近错误的用例。
:=
Postgres 9.0 - 9.4:从到过渡=>
分配给命名函数参数的 SQL 标准是=>
(并且Oracle 的 PL/SQL 使用它。Postgres 不能做同样的事情,因为该运算符以前是未保留的,所以它使用 PL/pgSQL 的赋值运算符:=
代替。随着 Postgres 9.0 的发布=>
已弃用用于其他目的。根据发行说明:
不赞成使用 => 作为运算符名称 (Robert Haas)
PostgreSQL 的未来版本可能会完全拒绝这个运算符名称,以支持命名函数参数的 SQL 标准表示法。目前,它仍然是允许的,但是在定义这样的操作符时会发出警告。
如果您应该=>
用于其他用途,请停止并停止。将来会破。
Postgres 9.5:=>
立即使用
从此版本开始,使用 SQL 标准运算符=>
。:=
仍然支持向后兼容。但是在不需要在非常旧的版本上运行的新代码中使用标准运算符。
这适用于函数调用(SQL 范围)中的命名参数赋值,而不适用:=
于保持不变的 plpgsql 代码中的赋值运算符。