plpgsql错误“表返回函数中的RETURN NEXT无法在具有OUT参数的函数中具有参数”

问题描述 投票:16回答:1

我在PostgreSQL 9.2中有一个plpgsql函数,该函数返回一个表。该函数运行多个SELECT,这些SELECT返回与该函数相同的列,然后根据某些检查返回这些结果或引发异常。我可以看到的唯一方法是使用FOR ... LOOP,但是我无法找出返回行的便捷方法。

我想做这样的事情:

CREATE OR REPLACE FUNCTION my_function()
RETURNS TABLE(column1 integer, column2 boolean, ...)
AS $BODY$
DECLARE
    result_row RECORD;
BEGIN
    FOR result_row IN (SELECT * FROM other_function_returning_same_columns()) LOOP
        IF something_wrong_with(result_row) THEN
            RAISE EXCEPTION 'Something went wrong';
        END IF;

        RETURN NEXT result_row;
    END LOOP;
END
$BODY$ LANGUAGE plpgsql STABLE;

这给我一个错误:

错误:RETURN NEXT无法在具有OUT参数的函数中使用参数

我不确定为什么Postgres在这里抱怨,因为我的代码看起来很像documentation中的示例,除了我的函数返回TABLE而不是SETOF之外。没有OUT参数。

我最终设法使它可以使用

RETURN QUERY SELECT result_row.column1, result_row.column2, ...;

但是必须一直列出所有列是很丑陋的,而且难以维护。我相信肯定有更好的方法。

postgresql exception-handling plpgsql
1个回答
24
投票

RETURN NEXT仅返回当前保留的输出参数。 RETURN NEXT

如果使用输出参数声明了该函数,则只写不带表达式的The manual

您反对:

没有RETURN NEXT参数。

输出参数在函数参数中用关键字OUTOUT声明,隐式包含在INOUT子句中:

RETURNS

这里,RETURNS TABLE(column1 integer, column2 boolean, ...) column1也是column2参数。

这应该做:

OUT

简单的注册类型

您可以使用注册的复合类型进一步简化:

CREATE OR REPLACE FUNCTION my_function()
  RETURNS TABLE(column1 integer, column2 boolean, ...)
  LANGUAGE plpgsql STABLE AS
$func$
BEGIN
   FOR column1, column2, ... IN 
      SELECT * FROM other_function_returning_same_columns()
   LOOP
      IF something_wrong_with(column1, column2, ...) THEN
         RAISE EXCEPTION 'Something went wrong';
      END IF;

      RETURN NEXT;
   END LOOP;
END
$func$;

或者,如果您的类型恰好与表定义匹配,则您已经具有该类型,因为每个表名都可以在PostgreSQL中用作类型名。然后简化:

CREATE TYPE mytype (column1 integer, column2 boolean, ...);

重新整理!

如果将CREATE OR REPLACE FUNCTION my_function() RETURNS SETOF mytype LANGUAGE plpgsql STABLE AS $func$ DECLARE _r mytype; BEGIN FOR _r IN SELECT * FROM other_function_returning_same_columns() LOOP IF something_wrong_with(_r) THEN RAISE EXCEPTION 'Something went wrong'; END IF; RETURN NEXT _r; END LOOP; END $func$; 命令集成到辅助函数RAISE中,则将逻辑求反并更方便地命名为something_wrong_with(),那么您可以使用以下简单查询完全替换everything_groovy()

my_function()

或将SELECT * FROM other_function_returning_same_columns() f WHERE everything_groovy(f); 集成到基本函数RAISE中,以进一步简化(使其更快)。如果只想在某些情况下使用other_function_returning_same_columns(),则可以随时添加一个参数(使用默认值)以将其打开/关闭。

© www.soinside.com 2019 - 2024. All rights reserved.