A.H*_*.H. 41 postgresql plpgsql assignment-operator colon-equals
PL/pgSQL的文档说,变量的声明和赋值完成:=.但是简单,更短,更现代 (见脚注) =似乎按预期工作:
CREATE OR REPLACE FUNCTION foo() RETURNS int AS $$
DECLARE
i int;
BEGIN
i = 0;
WHILE NOT i = 25 LOOP
i = i + 1;
i = i * i;
END LOOP;
RETURN i;
END;
$$ LANGUAGE plpgsql;
> SELECT foo();
25
Run Code Online (Sandbox Code Playgroud)
请注意,Pl/pgSQL可以清楚地区分分配和比较,如行中所示
WHILE NOT i = 25 LOOP
Run Code Online (Sandbox Code Playgroud)
所以,问题是:
=代替的已知后果:=?编辑/脚注:
请使用" 简短,不完整和错误的编程语言历史 "中的"更现代"部分:
1970年 - Niklaus Wirth创建了Pascal,一种程序语言.批评者立即谴责Pascal,因为它使用"x:= x + y"语法而不是更熟悉的类C"x = x + y".尽管C还没有被发明,但这种批评仍在发生.
1972年 - 丹尼斯·里奇发明了一种强大的枪,同时向前和向后射击.他对发明C和Unix的死亡和永久性伤害的数量不满意.
fil*_*rem 42
在PL/PgSQL解析器中,赋值运算符定义为
assign_operator : '='
| COLON_EQUALS
;
Run Code Online (Sandbox Code Playgroud)
这是一个遗留特性,自1998年引入源代码时就出现了 - 正如我们在PostgreSQL Git仓库中看到的那样.
从版本9.4开始,它是经过特殊记录的.
这个特性 - 有两个运算符用于同一事物 - 在pgsql用户列表中引发,有些人要求将其删除,但它仍然保留在核心中,因为遗留代码的公平语料库依赖于它.
所以,直接回答你的问题:
我没有在文档中找到提及和/或解释这个的部分吗?
您没有找到它,因为它没有记录,从版本9.4开始修复.
使用=而不是:=有任何已知的后果吗?
使用=没有任何副作用,但您应该使用:=进行赋值以使您的代码更具可读性,并且(作为副作用)与PL/SQL更兼容.
更新:在极少数情况下可能会产生副作用(参见Erwin的回答)
更新:感谢丹尼尔,桑迪和其他人的意见.
Erw*_*ter 30
将值分配给PL/pgSQL变量写为:
variable { := | = } expression;[...]
=可以使用Equal()代替PL/SQL兼容:=.
是否有使用
=代替的已知后果:=?
是的,我有一个严重后果的案例:使用命名参数调用函数 - 这是相关但不完全相同的事情.
严格地说,在这种情况下的区别在于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;
Run Code Online (Sandbox Code Playgroud)
旁白:注意=在函数定义中正确使用.这是CREATE FUNCTION语法的一部分- 以SQL赋值的方式.2
使用命名表示法的函数调用:
SELECT * FROM f_oracle(is_true := TRUE);
Run Code Online (Sandbox Code Playgroud)
Postgres标识:=为参数分配,一切都很好.但是:
SELECT * FROM f_oracle(is_true = TRUE);
Run Code Online (Sandbox Code Playgroud)
由于=是SQL等式运算符,Postgres is_true = TRUE在调用语句的上下文中将其解释为SQL表达式,并在将结果作为未命名的位置参数传递之前尝试对其进行求值.它is_true在外部范围中查找标识符.如果找不到:
Run Code Online (Sandbox Code Playgroud)ERROR: column "is_true" does not exist
这是幸运的情况,幸运的是,也是常见的情况.
如果is_true 可以在外部作用域中找到(并且数据类型是兼容的),is_true = TRUE则是一个有效的表达式,其boolean结果可被函数接受.没有错误发生.显然,这是程序员使用SQL相等运算符的意图=......
这个SQL小提琴演示了这种效果.
很辛苦,如果你不知道之间的区别的调试=和:=.
始终使用正确的操作员.
1在函数调用中使用命名表示法时,只有:=正确的赋值运算符.这适用于所有语言的功能,而不仅仅是PL/pgSQL,包括第9.4页.见下文.
2
可以使用=(或DEFAULT)来定义函数参数的默认值.这与任何方面的问题无关.它非常接近不正确的用例.
:=到=>分配给命名函数参数的SQL标准是=>(并且Oracle的PL/SQL使用它 .Postgres不能这样做,因为操作符以前是未保留的,所以它使用PL/pgSQL的赋值运算符:=.随着Postgres 9.0的发布=>用于其他目的的使用已被弃用.每个发行说明:
不推荐使用=>作为运营商名称(Robert Haas)
PostgreSQL的未来版本可能会完全拒绝此运算符名称,以支持命名函数参数的SQL标准表示法.目前,它仍然被允许,但是在定义这样的操作符时会发出警告.
如果你应该使用=>其他东西,停止和停止.它将来会破裂.
=>现在使用从此版本开始,使用SQL标准运算符=>.:=仍然支持向后兼容性.但是在新代码中使用标准运算符,不需要在非常旧的版本上运行.
这适用于函数调用(SQL范围)中的命名参数赋值,而不适用:=于plpgsql代码中的赋值运算符,该代码运算符保持不变.
| 归档时间: |
|
| 查看次数: |
8254 次 |
| 最近记录: |