gpt4 book ai didi

postgresql - "INSERT INTO ... FETCH ALL FROM ..."无法编译

转载 作者:行者123 更新时间:2023-11-29 11:36:37 24 4
gpt4 key购买 nike

我在 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;

但是有更好的方法吗?

最佳答案

不幸的是,INSERTSELECT 不能访问整个游标。

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

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();

参见:

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

注意:由于源是一个游标,所以只有第一次调用会成功。第二次执行该函数将返回一个空集。您需要一个带有 SCROLL option 的光标并移动到重复调用的开头。

关于postgresql - "INSERT INTO ... FETCH ALL FROM ..."无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50837548/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com