在 PostgreSQL 函数中声明并返回自定义类型

2024-04-24

我找到了这篇文章:

http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions 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$

但我似乎看不到/发现问题。


您尝试使用的语法对于 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函数 http://www.postgresql.org/docs/current/interactive/xfunc-sql.html反而。

定义一个临时行类型 with RETURNS TABLE () http://www.postgresql.org/docs/current/interactive/sql-createfunction.html。因为您没有提供表定义,所以我临时设置了列类型。这也适用于 plpgsql 函数。

Also:

  • 使用适当的JOIN状况 http://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FROM为了更好的可读性。

  • 使用表别名简化查询。

  • 使用数据类型boolean http://www.postgresql.org/docs/current/interactive/datatype-boolean.html for widget_details.active_yn.

布尔值

正如评论中所澄清的,它已经是一个布尔列。我建议使用TRUE / FALSE而不是数据输入的字符串文字 't' / 'f' - 引用关于布尔类型的手册 http://www.postgresql.org/docs/current/interactive/datatype-boolean.html:

关键词TRUE and FALSE是首选(符合 SQL 的)用法。

In a WHERE子句,每个表达式都被评估为boolean结果。TRUE符合资格,FALSE or NULL不要。所以,对于一个boolean类型,您可以简化:

   AND    d.active_yn = TRUE

to just:

   AND    d.active_yn
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PostgreSQL 函数中声明并返回自定义类型 的相关文章

随机推荐