我找到了这篇文章:
http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions
我试图用它作为我的功能的一个例子。 我从不同的表中选择不同的列,并尝试返回一组记录。
这是我的代码:
CREATE OR REPLACE FUNCTION get_details_for_widget(widgetid integer)
RETURNS SETOF widgetdetails AS
$BODY$
DECLARE
rec widgetdetails %rowtype;
BEGIN
FOR rec IN (
SELECT widget_details.id, widget_details.contact_id, widget_details.priority, widget_owner.contact
FROM widget_details, widget_owner
WHERE widget_details.rid=widgetid
AND widget_details.active_yn = 't'
AND widget_owner.id=widget_details.contact_id
Order by widget_details.priority ASC)
LOOP
RETURN NEXT rec;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
当我尝试编译此代码时,我得到错误类型" widgetdetails"不存在。根据wiki中的示例,我将逻辑更改为:
CREATE OR REPLACE FUNCTION get_details_for_widget(widgetid integer)
RETURNS SETOF widgetdetails AS
'SELECT widget_details.id, widget_details.contact_id,
widget_details.priority, widget_owner.contact
FROM widget_details, widget_owner
WHERE widget_details.rid=widgetid
AND widget_details.active_yn = "t"
AND widget_owner.id=widget_details.contact_id
Order by widget_details.priority ASC'
$BODY$
DECLARE
rec widgetdetails %rowtype;
BEGIN
FOR rec IN (
SELECT widget_details.id, widget_details.contact_id, widget_details.priority, widget_owner.contact
FROM widget_details, widget_owner
WHERE widget_details.rid=widgetid
AND widget_details.active_yn = 't'
AND widget_owner.id=widget_details.contact_id
Order by widget_details.priority ASC)
LOOP
RETURN NEXT rec;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
它给我一个错误说:
ERROR: syntax error at or near "$BODY$
但我似乎无法看到/发现问题。
答案 0 :(得分:3)
您尝试使用的语法对Postgres来说是陌生的。
您的代码比它需要的复杂得多。使用简单的SQL函数:
CREATE OR REPLACE FUNCTION get_details_for_widget(widgetid integer)
RETURNS TABLE (id int, contact_id int, priority int, contact text)
$func$
SELECT d.id, d.contact_id, d.priority, o.contact
FROM widget_details d
JOIN widget_owner o ON o.id = d.contact_id
WHERE d.rid = widgetid -- where does widgetid come from?
AND d.active_yn = 't'
ORDER BY d.priority
$func$ LANGUAGE sql
对于这样一个简单的函数,你根本不需要plpgsql。请改用普通SQL function。
使用RETURNS TABLE ()
定义 ad-hoc行类型。由于您未提供表定义,因此我使用列类型进行了即兴创作。这也适用于plpgsql函数。
此外:
使用合适的JOIN
condition以提高可读性。
使用表别名简化查询。
对widget_details.active_yn
使用数据类型boolean
。
正如评论中所阐明的那样,它已经是一个布尔列。我建议使用TRUE
/ FALSE
代替字符串文字't'/'f'进行数据输入 - 引用the manual about the boolean type:
关键字
TRUE
和FALSE
是首选(符合SQL)用法。
在WHERE
子句中,每个表达式都被计算为boolean
个结果。 TRUE
符合条件,FALSE
或NULL
不符合条件。因此,对于boolean
类型,您可以简化:
AND d.active_yn = TRUE
只是:
AND d.active_yn
答案 1 :(得分:2)
要使用自定义复合类型,您必须先使用CREATE TYPE
创建它。
示例,松散地基于您的查询(使用实际数据类型进行更改):
CREATE TYPE widgetdetails AS (
id INT,
contact_id INT,
widget_details INT,
contact TEXT
);
只有在创建此类型后才能接受此声明:
DECLARE
rec widgetdetails;
...
同样对于CREATE FUNCTION
的语法,坚持你的第一个版本,第二次尝试有严重的问题,并没有帮助。