我在后端使用postgresql 8.4
我有一个postgres函数说A()它可以返回一组记录(3列),如:
<A_id>::int,<A_ts_1>::timestamp,<A_ts_2>::timestamp
function A这样定义(例如):
CREATE OR REPLACE FUNCTION A()
RETURNS SETOF record AS
$$
DECLARE
BEGIN
RETURN QUERY SELECT DISTINCT ON (A.id) A.id, A.ts_1, A.ts_2 FROM tablea;
END;
$$ LANGUAGE plpgsql;
SQL
函数A已在另一个函数B中调用。在函数B中,我需要一个变量来保存从A()返回的内容,然后执行一些查询,例如:
<variable> = select * from A();
a_id_array = ARRAY(select A_id from <variable>);
a_filtered_array = ARRAY(select A_id from <variable> where A_ts_1 ><a_timestamp> and A_ts_2 < <a_timestamp>);
所以我的问题是我应该定义什么变量来保存从A()返回的记录集。
我试过临时表,这对多会话env来说真的不好,它会阻止数据插入。 postgresql create temp table could block data insertion?
我检查了doc的视图似乎不符合我的要求,但是我可能会错,所以如果你们中的任何一个人可以给我一个关于如何在这种情况下使用视图的想法并使用视图也会阻止数据插入?
谢谢大家!
P.S。 我认为更糟糕的情况是在函数B()中我调用函数A()两次,例如:
a_id_array = ARRAY(select A_id from A());
a_filtered_array = ARRAY(select A_id from A() where A_ts_1 ><a_timestamp> and A_ts_2 < <a_timestamp>);
然后我的问题会略有改变,我是否可以使用一个函数调用A()来实现这种情况?
答案 0 :(得分:0)
PostgreSQL没有(但是,从postgres 10开始)有一个由tuplestore支持的表值变量。所以你最好的选择是:
返回REFCURSOR
并从其他功能中使用它。由于您无法轻松地重复使用结果集或在子查询中重用FETCH
,因此使用起来可能很笨拙。生成游标结果集并不总是很容易,具体取决于您创建结果的方式。
使用生成名称的临时表,以免它们发生冲突。这里涉及很多动态SQL(EXECUTE format(...)
),但它有效。
避免尝试在函数之间传递结果集
答案 1 :(得分:0)
经过研究,找到了一种方法来替换使用临时表和查询使用 WITH查询的返回记录集。
SELECT c.r_ids, c.a_r_ids into a_id_array, a_filtered_array FROM(
WITH returned_r AS (SELECT * FROM a())
SELECT * from (
SELECT ARRAY( SELECT A_id from returned_r ) as r_ids ) as a
CROSS JOIN (
SELECT ARRAY(SELECT A_id FROM returned_r WHERE A_ts_1 is NOT NULL AND A_ts_2 IS NULL) as a_r_ids
) as b
) as c;