我在Postgresql 9.2中有一个plpgsql函数,它返回一个表.该函数运行多个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;
这给我一个错误:
ERROR: RETURN NEXT cannot have a parameter in function with OUT parameters
我不知道为什么Postgres在这里抱怨,因为我的代码看起来很像documentation的例子,除了我的函数返回TABLE而不是SETOF.没有OUT参数.
我最终设法让它工作使用
RETURN QUERY SELECT result_row.column1,result_row.column2,...;
但是必须一直列出所有的列是难以维护的.我肯定有一个更好的方法.
RETURN NEXT只返回在您的RETURNS子句(column1,column2,..)中声明的参数当前持有.您不能为此表单提供参数.
There are no OUT parameters.
在RETURNS TABLE(column1 integer,…)中声明的参数与OUT参数实际上相同.
这应该做到:
CREATE OR REPLACE FUNCTION my_function() RETURNS TABLE(column1 integer,...) AS $BODY$ BEGIN FOR column1,... IN SELECT * FROM other_function_returning_same_columns() LOOP IF something_wrong_with(column1,...) THEN RAISE EXCEPTION 'Something went wrong'; END IF; RETURN NEXT; END LOOP; END $BODY$LANGUAGE plpgsql STABLE;
更简单的注册类型
您可以使用注册的复合类型进一步简化:
CREATE TYPE mytype (column1 integer,...);
或者,如果您的类型与表定义相匹配,那么您已经具有该类型,因为每个表名可以用作Postgresql中的类型名称.然后简化:
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()中以进一步简化(并使其更快).如果您只想在某些情况下升级除外,您可以随时添加一个参数(默认值)来打开/关闭它.