在用户定义的函数中,如何返回由连接其他表的投影形成的表?
这是一个简单的例子
CREATE FUNCTION something123(character varying(100)) RETURNS TABLE (a integer, b character varying(300)) AS
$$
SELECT b.year, p.materialUsed FROM bestBefore b join packaged p on b.id=p.id WHERE id=$1;
$$
LANGUAGE SQL
;
它总是在TABLE出错。你如何获得该select语句的内容?
我正在使用Postgres 8.1.21
答案 0 :(得分:4)
您的代码很好,但您的PostgreSQL版本不是。根据{{3}},它不支持RETURNS TABLE
。
在非常老的PostgreSQL版本(如8.1)上,您必须在不使用RETURNS SETOF RECORD
的情况下声明RETURNS TABLE
,因为旧版本不支持此版本。 RETURNS SETOF RECORD
导致函数返回匿名记录集。然后,您必须在呼叫站点指定记录结构,如下所示:
regress=# CREATE FUNCTION something123_legacy(character varying(100))
RETURNS SETOF RECORD AS
$$
SELECT 1, 'fred'::varchar(300);
$$
LANGUAGE SQL;
regress=# SELECT * FROM something123_legacy('blah') somethingresult(col1name integer, col2name character varying(300));
col1name | col2name
----------+----------
1 | fred
(1 row)
或者,您可以CREATE TYPE
创建已定义的行类型,或使用现有的表类型,因为每个表都具有相同名称的行类型。然后,您的函数可以返回该行类型。
regress=# CREATE TYPE something123type AS (col1name integer, col2name character varying(300));
CREATE TYPE
regress=# CREATE FUNCTION something123_legacy2(character varying(100))
RETURNS SETOF something123type AS
$$
SELECT 1, 'fred'::varchar(300);
$$
LANGUAGE SQL;
CREATE FUNCTION
regress=# SELECT * FROM something123_legacy2('blah');
col1name | col2name
----------+----------
1 | fred
(1 row)
您也可以尝试使用OUT
参数,但我似乎依稀记得它们一度只支持PL / PgSQL(不是SQL函数)而且我不确定它们是否适用于8.1。试试吧:
CREATE FUNCTION something123( IN character varying(100), OUT integer, OUT character varying(300) ) RETURNS setof record AS
$$
SELECT b.year, p.materialUsed FROM bestBefore b join packaged p on b.id=p.id WHERE id=$1;
$$
LANGUAGE SQL;
警告:the PostgreSQL 8.1 documentation for CREATE FUNCTION
。 没有获得安全性或错误修复。最终你将不得不升级,等待的时间越长它就越难。立即开始规划升级。阅读您和当前版本之间的每个.0版本(8.2.0,8.3.0等)的发行说明,特别注意升级说明和兼容性说明。注意删除隐式强制转换为text,bytea_output更改和standard_conforming字符串更改。阅读新版本手册的升级部分,并注意使用新版本pg_dump
等建议。