Postgresql “遗忘赋值运算符”=&引用;还有一句俗话:“什么=&引用;
PL/pgSQL的文档说明,变量的声明和赋值是通过Postgresql “遗忘赋值运算符”=&引用;还有一句俗话:“什么=&引用;,postgresql,plpgsql,assignment-operator,colon-equals,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 LO
:=
完成的。
但一个简单、更短、更现代(见脚注)=似乎如预期的那样起作用:
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
请注意,Pl/pgSQL可以清楚地区分赋值和比较,如第行所示
WHILE NOT i = 25 LOOP
因此,问题是:
- 我没有在文件中找到提到和/或解释这一点的部分吗
- 使用
而不是=
是否有任何已知的后果:=
阅读Postgresql 9文档: 在运算符优先级表中列出“=”作为赋值运算符
但奇怪的是(作业操作员文档)没有提到它。我自己的问题的部分答案: PL/pgSQL部分显示了使用特殊语法的两个示例:
GET DIAGNOSTICS variable = item [ , ... ];
GET DIAGNOSTICS integer_var = ROW_COUNT;
我尝试了:=
和=
两种方法,它们都能工作
但是,
GET DIAGNOSTICS
是一种特殊的语法,因此可以说,这也不是一种正常的PL/pgSQL赋值操作
assign_operator : '='
| COLON_EQUALS
;
这是一个遗留特性,自1998年引入以来一直存在于源代码中,正如我们在中看到的
从9.4版开始就是这样
pgsql用户列表中提出了这种特性,即同一事物有两个操作符,一些人要求删除它,但它仍然保留在核心,因为传统代码的公平主体依赖于它
看这个
因此,要直接回答您的问题:
我没有在文件中找到提到和/或解释的部分吗
这个
您没有找到它,因为它是未记录的,从9.4版起已修复
使用=而不是:=,是否存在任何已知的后果
使用=没有副作用,但您应该使用:=进行赋值,以使代码更可读,并且(作为副作用)与PL/SQL更兼容
更新:在极少数情况下可能会有副作用(见欧文的回答)
更新:由于Daniel、Sandy和其他人的输入,答案更新 Q1 这最终是: PL/pgSQL变量的赋值写为:
变量{:=|=}表达式代码>
可以使用[…]Equal(=
)代替符合PL/SQL的:=
问题2
使用=
而不是:=
是否有任何已知的后果
是,我有一个严重后果的案例:使用命名参数调用函数——这是相关的,但并不完全相同
严格地说,这种情况下的区别是在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函数
语法的一部分-以SQL赋值的方式。2
使用命名符号的函数调用:
Postgres将:=
识别为参数赋值,一切正常但是:
SELECT * FROM f_oracle(is_true = TRUE);
由于=
是SQL相等运算符,因此Postgres在调用语句的上下文中将is_true=true
解释为SQL表达式,并在将结果作为未命名位置参数传递之前尝试对其求值。它在外部范围中查找标识符是否为true
。如果找不到:
这是一个幸运的案例,幸运的是,也是一个常见的案例
当可以在外部范围中找到is_true
时(且数据类型兼容),is_true=true
是一个有效表达式,其结果为函数接受的布尔值。没有错误发生。显然,这是使用SQL相等运算符的程序员的意图
这证明了这种效果
如果您不知道=
和之间的区别:=
始终使用正确的操作员
1使用时,只有:=
是正确的赋值运算符。这适用于所有语言的函数,而不仅仅是PL/pgSQL,直到并包括第9.4页。见下文
二,
可以使用=
(或默认值
)来定义。这与手头的问题毫无关系。它非常接近于不正确的用例
Postgres 9.0-9.4:从:=
过渡到=>
指定给命名函数参数的SQL标准是=>
(和.Postgres不能做同样的事情,因为该操作符以前没有保留,所以它使用PL/pgSQL的赋值操作符:=
。随着Postgres 9.0的发布,将=>
用于其他目的已被弃用。)
不赞成使用=>作为运算符名称(Robert Haas)
PostgreSQL的未来版本可能会拒绝此运算符名称
完全是为了支持命名对象的SQL标准表示法
函数参数。目前,它仍然是允许的,但是
警告是em
SELECT * FROM f_oracle(is_true = TRUE);
ERROR: column "is_true" does not exist