加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – “INSERT INTO … FETCH ALL FROM …”无法编译

发布时间:2020-12-13 15:53:45 所属栏目:百科 来源:网络整理
导读:我在PostgreSQL 9.6上有一些函数返回游标(refcursor): CREATE OR REPLACE FUNCTION public.test_returning_cursor() RETURNS refcursorIMMUTABLELANGUAGE plpgsqlAS $$DECLARE _ref refcursor = 'test_returning_cursor_ref1';BEGIN OPEN _ref FOR SELECT '
我在PostgreSQL 9.6上有一些函数返回游标(refcursor):

CREATE OR REPLACE FUNCTION public.test_returning_cursor()
  RETURNS refcursor
IMMUTABLE
LANGUAGE plpgsql
AS $$
DECLARE
  _ref refcursor = 'test_returning_cursor_ref1';
BEGIN
  OPEN _ref FOR
  SELECT 'a' :: text AS col1
  UNION
  SELECT 'b'
  UNION
  SELECT 'c';

  RETURN _ref;
END
$$;

我需要编写另一个函数,在该函数中创建临时表,并将来自此refcursor的所有数据插入其中.但INSERT INTO … FETCH ALL FROM …似乎是不可能的.这样的功能无法编译:

CREATE OR REPLACE FUNCTION public.test_insert_from_cursor()
  RETURNS table(col1 text)
IMMUTABLE
LANGUAGE plpgsql
AS $$
BEGIN
  CREATE TEMP TABLE _temptable (
    col1 text
  ) ON COMMIT DROP;

  INSERT INTO _temptable (col1)
  FETCH ALL FROM "test_returning_cursor_ref1";

  RETURN QUERY
  SELECT col1
  FROM _temptable;
END
$$;

我知道我可以使用:

FOR _rec IN
  FETCH ALL FROM "test_returning_cursor_ref1"
LOOP
  INSERT INTO ...
END LOOP;

但有更好的方法吗?

解决方法

不幸的是,INSERT和SELECT无法访问整个游标.

为避免昂贵的单行INSERT,您可以使用RETURNS TABLE的中间函数,并使用RETURN QUERY将光标作为表返回.看到:

> Return a query from a function?

CREATE OR REPLACE FUNCTION f_cursor1_to_tbl()
  RETURNS TABLE (col1 text) AS
$func$
BEGIN
   -- MOVE BACKWARD ALL FROM test_returning_cursor_ref1;  -- optional,see below

   RETURN QUERY
   FETCH ALL FROM test_returning_cursor_ref1;
END
$func$ LANGUAGE plpgsql;  -- not IMMUTABLE

然后直接创建临时表,如:

CREATE TEMP TABLE t1 ON COMMIT DROP
AS SELECT * FROM f_cursor1_to_tbl();

看到:

> Creating temporary tables in SQL

仍然不是很优雅,但比单行INSERT快得多.

注意:由于源是游标,因此只有第一次调用成功.第二次执行该函数将返回一个空集.你需要一个带有SCROLL option的光标,然后移动到重复调用的开始.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读