Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql “遗忘赋值运算符”=&引用;还有一句俗话:“什么=&引用;_Postgresql_Plpgsql_Assignment Operator_Colon Equals - Fatal编程技术网

Postgresql “遗忘赋值运算符”=&引用;还有一句俗话:“什么=&引用;

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

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
请注意,Pl/pgSQL可以清楚地区分赋值和比较,如第行所示

      WHILE NOT i = 25 LOOP
因此,问题是:

  • 我没有在文件中找到提到和/或解释这一点的部分吗
  • 使用
    =
    而不是
    :=
    是否有任何已知的后果
编辑/脚注:

请在“更现代”部分眨眨眼,如:

1970年的今天,Niklaus Wirth创建了一种过程语言Pascal。评论家 立即谴责Pascal,因为它使用“x:=x+y”语法 而不是像“x=x+y”这样更为熟悉的C。这一批评 尽管C语言还没有被发明出来,它还是发生了

1972年的今天,丹尼斯·里奇发明了一种威力强大的枪,可以同时向前射击 同时向后移动。对死亡人数不满意 他发明了C和Unix,这是他发明的永久性缺陷


阅读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