PostgreSQL 8.1中的SQL函数“RETURNS TABLE”语法错误

时间:2012-10-24 08:10:18

标签: sql postgresql user-defined-functions

在用户定义的函数中,如何返回由连接其他表的投影形成的表?

这是一个简单的例子

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

1 个答案:

答案 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等建议。