Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.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 变量如何在PL/pgSQL函数中工作_Postgresql_Plpgsql - Fatal编程技术网

Postgresql 变量如何在PL/pgSQL函数中工作

Postgresql 变量如何在PL/pgSQL函数中工作,postgresql,plpgsql,Postgresql,Plpgsql,我不熟悉plpgsql函数 有人能解释一下这是怎么回事吗 CREATE OR REPLACE FUNCTION test1( IN a TEXT, IN b TEXT ) RETURNS void AS $func$ DECLARE cnt INT2; BEGIN SELECT COUNT(*) INTO STRICT

我不熟悉plpgsql函数

有人能解释一下这是怎么回事吗

CREATE OR REPLACE FUNCTION test1(
    IN a TEXT,
    IN b  TEXT
        )
        RETURNS void AS $func$
        DECLARE
          cnt INT2;
        BEGIN
          SELECT
            COUNT(*)
          INTO STRICT
            cnt
          FROM
            pg_catalog.pg_class
          WHERE 1 = 1
            AND a = $1
            AND b = $2;
        RAISE NOTICE '%', cnt;
        END; $func$
        LANGUAGE plpgsql;

postgres=# SELECT test1('1', '2');
NOTICE:  311
 test1
-------

(1 row)

为什么它会起作用?我们在pg_类中没有a和b属性?为什么通知会返回pg_类的
select*的结果?

您正在这样做:

SELECT
    COUNT(*)
FROM
    pg_catalog.pg_class
WHERE 1 = 1
AND '1' = '1'
AND '2' = '2';

count 
-------
   554


SELECT
    COUNT(*)
FROM
    pg_catalog.pg_class
;

count 
-------
   554
这是真的,所以你可以得到与此相同的结果:

SELECT
    COUNT(*)
FROM
    pg_catalog.pg_class
WHERE 1 = 1
AND '1' = '1'
AND '2' = '2';

count 
-------
   554


SELECT
    COUNT(*)
FROM
    pg_catalog.pg_class
;

count 
-------
   554
如果你想让它失败,消除它的模糊性:

CREATE OR REPLACE FUNCTION public.test1(a text, b text)
 RETURNS void
 LANGUAGE plpgsql
AS $function$
        DECLARE
          cnt INT2;
        BEGIN
          SELECT
            COUNT(*)
          INTO STRICT
            cnt
          FROM
            pg_catalog.pg_class
          WHERE 1 = 1
            AND pg_catalog.pg_class.a = $1
            AND pg_catalog.pg_class.b = $2;
        RAISE NOTICE '%', cnt;
        END; $function$
;

select test1('1', '2');
ERROR:  column pg_class.a does not exist
LINE 6:             AND pg_catalog.pg_class.a = $1
                        ^
QUERY:  SELECT
            COUNT(*)
                                                FROM
            pg_catalog.pg_class
          WHERE 1 = 1
            AND pg_catalog.pg_class.a = $1
            AND pg_catalog.pg_class.b = $2
CONTEXT:  PL/pgSQL function test1(text,text) line 5 at SQL statement


有关更多信息,请参阅:

“由于变量的名称在语法上与表列的名称没有区别,因此也引用表的语句中可能存在歧义:给定的名称是指表列还是指变量?让我们将前面的示例更改为

插入dest(col),从src中选择foo+bar

在这里,dest和src必须是表名,col必须是dest的一列,但foo和bar可能是函数的变量,也可能是src的列

默认情况下,如果SQL语句中的名称可能引用变量或表列,PL/pgSQL将报告错误。您可以通过重命名变量或列、限定不明确的引用或告诉PL/pgSQL首选哪种解释来解决此问题

最简单的解决方案是重命名变量或列。常见的编码规则是对PL/pgSQL变量使用与列名不同的命名约定。例如,如果您始终将函数变量命名为v_,而列名中没有一个以v_开头,则不会发生冲突

或者,您可以限定不明确的引用以使其清晰。在上面的示例中,src.foo将是对表列的明确引用。要创建对变量的明确引用,请在带标签的块中声明它,并使用块的标签(参见第42.2节)。例如,“…”