你的代碼是好的,但你的PostgreSQL的版本是沒有的。它不支持RETURNS TABLE
,根據the PostgreSQL 8.1 documentation for CREATE FUNCTION
。
在像8.1這樣極其陳舊的PostgreSQL版本中,您必須聲明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;
警告:Your PostgreSQL version is unsupported and has been for two years。這是沒有得到安全或錯誤修復。最終你將不得不升級,而你越等待它越難獲得。現在開始計劃升級。閱讀您和當前版本之間每個.0版本(8.2.0,8.3.0等)的版本說明,特別注意升級說明和兼容性說明。注意將隱式轉換刪除到文本,bytea_output更改和standard_conforming字符串更改。閱讀新版本手冊的升級部分,並注意使用新版本pg_dump
的建議。
答案更新以反映版本。特別是當使用真正古老的PostgreSQL 8.1版本(2005年11月發佈,2010年11月最終更新)時,請在所有問題中明確提及您的版本。 –
@CraigRinger我應該使用 select version();在Postgres或psql - 版本在終端?他們爲什麼不同呢? – Celeritas
他們當然是不同的。在大多數系統中,它們會產生相同的結果,但'SELECT version()'產生* server *版本,而'psql --version'則打印'psql'客戶端的版本。完全可以使用(比如說)psql 9.2連接到PostgreSQL 8.4,所以版本不一定相同。對於大多數問題,這是你關心的服務器版本,這就是爲什麼'select version()'是首選的。有些系統(通常是Mac OS X)通常會在其上安裝多個PostgreSQL版本,因此瞭解它是服務器版本可能很重要。 –