ошибка plpgsql "RETURN NEXT не может иметь параметр в функции без параметров" в функции возврата таблицы

у меня есть функция plpgsql в PostgreSQL 9.2, которая возвращает таблицу. Функция выполняет несколько выборок, возвращающих те же столбцы, что и функция, а затем возвращает эти результаты или создает исключение, в зависимости от некоторых проверок. Единственный способ, который я вижу, это сделать это с FOR ... Петля, но я не могу найти удобный способ вернуть строку.

Я хочу сделать что-то вроде этого:

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 не может иметь параметр в функции без параметров

Я не уверен, почему Postgres жалуется здесь, потому что мой код выглядит очень похоже на пример в документация, за исключением того, что моя функция возвращает таблицу вместо SETOF. Нет никаких параметров.

мне в конце концов удалось заставить его работать с помощью

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

но необходимость перечислять все столбцы все время уродлива и сложнее поддерживать. Я уверен, что должен быть лучший способ.

1 ответов


RETURN NEXT просто возвращает то, что параметры, объявленные в RETURNS п. (column1, column2, ..) в настоящее время провести. Вы не можете предоставить параметр для этой формы.

нет никаких параметров OUT.

параметры, объявленные в RETURNS TABLE(column1 integer, column2 boolean, ...) эффективно тот же as OUT параметры.

это должно сделать это:

CREATE OR REPLACE FUNCTION my_function()
  RETURNS TABLE(column1 integer, column2 boolean, ...) AS
$BODY$
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
$BODY$ LANGUAGE plpgsql STABLE;

проще с зарегистрированным типом

вы можете дальше упростить с a зарегистрированный составной тип:

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

или, если ваш тип совпадает с определением таблицы, у вас уже есть этот тип, потому что каждое имя таблицы может использоваться как имя типа в 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() для дальнейшего упрощения (и сделать его быстрее). Если вы только хотите RAISE EXCEPTION в некоторых ситуациях, вы всегда можете добавить параметр (по умолчанию) вкл / выкл.