当前位置: 首页 > 面试题库 >

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

乐正秦斩
2023-03-14
问题内容

我发现这篇文章:

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函数。

定义一个 临时排式RETURNS TABLE ()。由于您没有提供表定义,因此我临时使用了列类型。这同样适用于plpgsql函数。

还:

  • 使用适当的JOIN条件以获得更好的可读性。

  • 使用表别名简化查询。

  • 将数据类型boolean用于widget_details.active_yn

布尔值

如评论中所阐明的,它已经是一个布尔列。我建议使用TRUE/FALSE代替字符串文字’t’/’f’进行数据输入-
引用有关布尔类型的手册:

关键字TRUEFALSE是首选(与SQL兼容)的用法。

WHERE子句中,每个表达式都将求值为boolean结果。TRUE合格FALSE或不合格NULL。因此,对于boolean类型,您可以简化:

   AND    d.active_yn = TRUE

只是:

   AND    d.active_yn


 类似资料:
  • 我在这里查过了https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md这是TypeScript语言规范,但我找不到如何声明函数的返回类型。 我在下面的代码中展示了我所期望的: 我知道我可以用

  • 请帮帮我,为什么我得到的错误函数不存在? [2018-10-31 12:31:05][42883]错误:函数companytester(bigint,未知,未知,未知)不存在 提示:没有与给定名称和参数类型匹配的函数。您可能需要添加显式类型转换。

  • 我正在考虑将Auth0用于我的API和web应用程序,并进行查询。生成Jwt令牌时,我希望包含一些仅存在于我的用户数据库中的自定义用户声明。这是可能的,还是所有声明都需要作为Auth0中的预定义属性存在。 我有自己的用户数据库,因为我需要在那里存储一些动态和复杂的用户权限。我意识到一个选择是不将这些权限存储在令牌中,我可以有一个单独的api来获取它们,但是为了性能和简单性,我宁愿将它们包装到Jwt

  • 对于我的Hi/Lo实现,我需要一个函数来获取独占表锁、更新值并选择一行。我想出了以下代码: 但是,在调用该函数时,它返回的不是一行,而是一列,内容类似于“未命名门户3”。我想我应该迭代返回的ref(但如何)? 我可以使用的另一种方法是使用UPDATE RETURNING语句,但是我不确定在这种情况下是否会出现竞争情况。任何帮助都将不胜感激。谢谢

  • 问题内容: 我目前正在阅读John Papa的AngularJS样式指南,并看到了以下代码: 您可以看到函数和是 在 函数返回值 之后 定义的。这是如何运作的?它是否符合标准并且可以在所有浏览器中使用(例如,来自IE 6)? 问题答案: 您可以看到函数和是在函数返回值之后定义的。 那是从它们的编写位置看的样子,是的,但是实际上它们是在函数中的任何分步代码完全运行之前定义的。有时这被称为“提升”函数

  • 问题内容: 我想在PostgreSQL上设置一个返回表的函数。这是该函数的源代码: 调用该函数仅返回一列,并用’,’分隔值: 我期望有不同的列(在函数的开头为表指定的每个值一个),而不仅仅是所有值的列。有谁知道为什么会这样,我该如何解决? 谢谢蒂莫 问题答案: 使用 代替 以获得表格的结果。 (像对待表一样处理该函数。)