我需要创建一个函数,它返回SELECT查询的结果。此SELECT查询是在此函数内创建的几个临时表的JOIN。有没有办法创造这样的功能?这是一个例子(它非常简化,实际上有多个带有长查询的临时表):
CREATE OR REPLACE FUNCTION myfunction () RETURNS TABLE (column_a TEXT, column_b TEXT) AS $$
BEGIN
CREATE TEMPORARY TABLE raw_data ON COMMIT DROP
AS
SELECT d.column_a, d2.column_b FROM dummy_data d JOIN dummy_data_2 d2 using (id);
RETURN QUERY (select distinct column_a, column_b from raw_data limit 100);
END;
$$
LANGUAGE 'plpgsql' SECURITY DEFINER
我收到错误:
[Error] Script lines: 1-19 ------------------------- ERROR: RETURN cannot have a parameter in function returning set; use RETURN NEXT at or near "QUERY"Position: 237
我提前为任何明显的错误道歉,我是新来的。
Psql版本 PostgreSQL 8.2.15(Greenplum Database 4.3.12.0 build 1)
答案 0 :(得分:2)
最新版本的Greenplum Database(5.0)基于PostgreSQL 8.3,它支持RETURN QUERY语法。刚刚测试了你的功能:
PostgreSQL 8.4devel (Greenplum Database 5.0.0-beta.10+dev.726.gd4a707c762 build dev)
答案 1 :(得分:1)
Postgres可能引发的最可能的错误:
错误:列“foo”指定了多次
意思是,两个表中至少还有一个列名称(除id
之外,它被折叠到一个带有USING
子句的实例)。这不会在容错重复输出列名的普通SQL SELECT
中引发异常。但是您无法创建具有重复名称的表。
问题也适用于 Greenplum (就像您之后声明的那样),即 不 Postgres。它于2005年从PostgreSQL分离出来并单独开发。目前的Postgres手册几乎不再适用。查看Greenplum documentation。
而psql只是标准的PostgreSQL交互式终端程序。显然你正在使用PostgreSQL 8.2.15附带的那个,但是RDBMS仍然是Greenplum,而不是Postgres。
语法修复(对于Postgres,就像你第一次标记的那样,仍然相关):
CREATE OR REPLACE FUNCTION myfunction()
RETURNS TABLE (column_a text, column_b text) AS
$func$
BEGIN
CREATE TEMPORARY TABLE raw_data ON COMMIT DROP AS
SELECT d.column_a, d2.column_b -- explicit SELECT list avoids duplicate column names
FROM dummy_data d
JOIN dummy_data_2 d2 using (id);
RETURN QUERY
SELECT DISTINCT column_a, column_b
FROM raw_data
LIMIT 100;
END
$func$ LANGUAGE plpgsql SECURITY DEFINER;
该示例不需要临时表 - 除非您在同一事务(ON COMMIT DROP
)中的函数调用之后访问临时表。另外,一个简单的SQL函数在各方面都更好。 Postgres的语法和 Greenplum:
CREATE OR REPLACE FUNCTION myfunction(OUT column_a text, OUT column_b text)
RETURNS SETOF record AS
$func$
SELECT DISTINCT d.column_a, d2.column_b
FROM dummy_data d
JOIN dummy_data_2 d2 using (id)
LIMIT 100;
$func$ LANGUAGE plpgsql SECURITY DEFINER;
至少,it should also work for Greenplum。
此功能的唯一剩余原因是SECURITY DEFINER
。否则,你可以使用简单的SQL语句(可能是预备语句)。
RETURN QUERY
在2008年被添加到版本8.3的PL / pgSQL中,有些年份在 Greenplum的分支之后。可能会解释你的错误信息:
ERROR: RETURN cannot have a parameter in function returning set; use RETURN NEXT at or near "QUERY" Position: 237
除此之外:LIMIT
没有ORDER BY
会产生任意结果。我假设你知道这一点。
如果由于某种原因你真的需要临时表并且无法升级到Greenplum 5.0 like A. Scherbaum suggested,你仍然可以在Greenplum 4.3.x中使用它(就像在Postgres 8.2中一样)。将 FOR
循环与 RETURN NEXT
结合使用。
例子: