首页 > 解决方案 > 如何使用 Refcursor 变量的值进行 FETCH

问题描述

我无法弄清楚如何使用 PostgreSQL 上的 Refcursor 变量的值进行 FETCH。

从这里查看reffunc2() 示例,如下所示:

CREATE FUNCTION reffunc2() RETURNS refcursor AS '
DECLARE
    ref refcursor;
BEGIN
    OPEN ref FOR SELECT col FROM test;
    RETURN ref;
END;
' LANGUAGE plpgsql;
BEGIN;
SELECT reffunc2();
FETCH ALL IN "<unnamed cursor 1>";
COMMIT;

这可行,但最终FETCH似乎需要提前知道光标的名称,然后对其进行硬编码!但是,根据我自己的实验,这个名称会有所不同,通常类似于"<unnamed portal 5>"(数量不同)。

我希望能够将示例的结尾更改为:

DO $$
DECLARE
foo refcursor;
BEGIN
SELECT reffunc2() INTO foo;
FETCH ALL IN foo;
END $$;

这样我就可以按名称选择,响应从reffunc2. 但是FETCH ALL IN foo

ERROR:  syntax error at or near ";"
LINE 6: FETCH ALL IN foo;
                        ^
********** Error **********

ERROR: syntax error at or near ";"
SQL state: 42601
Character: 85

我找不到任何方法来让它发挥作用。

编辑:

我只是尝试过这个(尽可能遵循将结果转换为的建议TEXT):

DO $$
DECLARE
foo text;
BEGIN
SELECT CAST(reffunc2() AS text) INTO foo;
FETCH ALL IN foo;
END $$;

但现在我明白了

ERROR:  variable "foo" must be of type cursor or refcursor
LINE 6: FETCH ALL IN foo;
                     ^
********** Error **********

ERROR: variable "foo" must be of type cursor or refcursor
SQL state: 42804
Character: 91

反而!(显然这一切都很好,除了在我以前的版本中,变量a refcursor,然后它只是给出了一个语法错误。)

标签: postgresql

解决方案


要命名游标,只需将字符串分配给refcursor变量:

DECLARE
    ref refcursor := ''willi'';

然后门户将具有该名称。

在打开游标之前指定名称很重要。

如果您不想指定名称,只需将函数结果转换为text,这将为您提供光标名称。

如何使用FETCH取决于你调用它的环境:

  • 如果你从 SQL 调用它,你必须这样做:

    FETCH ALL FROM willi;
    

    您必须使用函数的结果构造 SQL 语句,转换为text.

  • 如果你从 PL/pgSQL 调用它,你可以在FETCH语句中使用一个变量,但你必须为结果提供一个目的地:

    DECLARE
       r refcursor;
       x text;  -- use the correct type
    BEGIN
       r := reffunc2();
       FETCH NEXT FROM r INTO x;
    END;
    

推荐阅读