#postgresql #plpgsql
#postgresql #plpgsql
Вопрос:
Я пытаюсь изучить PL / pgSQL, написав несколько простых программ. Чтобы узнать о цикле FOREACH, я написал следующее:
CREATE OR REPLACE FUNCTION test(int[]) RETURNS void AS $$
DECLARE
window INT;
BEGIN
FOREACH window IN ARRAY $1
LOOP
EXECUTE 'SELECT $1' USING window;
END LOOP;
$$ LANGUAGE plpgsql;
SELECT test(ARRAY [30,60]);
Я ожидаю, что этот фрагмент кода будет сначала напечатан 30
, а затем 60
. Однако я получаю следующую ошибку.
psql:loop.sql:11: ERROR: syntax error at end of input
LINE 7: EXECUTE 'SELECT $1' USING window;
^
psql:loop.sql:13: ERROR: function test(integer[]) does not exist
LINE 1: SELECT test(ARRAY [30,60]);
^
HINT: No function matches the given name and argument types. You might need
to add explicit type casts.
Итак, в определении функции содержится синтаксическая ошибка, но я не понимаю, в чем ошибка и как ее исправить. Я был бы признателен за любую помощь. Спасибо!
Ответ №1:
Ваша функция объявлена как returns void
, поэтому вы ничего не можете вернуть из нее. Если вы хотите вернуть несколько значений, вам нужно использовать returns setof integer
Но у него больше проблем, чем это.
- вы должны присвоить своему параметру имя (не ошибка, а хороший стиль кодирования)
- чтобы вернуть значение из функции, которую вам нужно использовать
return
. Чтобы вернуть несколько значений (из-заreturns setof
), вам нужно использоватьreturn next
- нет необходимости в динамическом SQL для возврата значения, вы можете вернуть переменную напрямую.
- Также не не ошибка, но:
window
это ключевое слово, я бы не использовал переменную с таким именем.
Применяя все это, ваша функция должна выглядеть следующим образом:
CREATE OR REPLACE FUNCTION test(p_input int[])
RETURNS setof integer
as
$$
DECLARE
l_value INT;
BEGIN
FOREACH l_value IN ARRAY p_input
LOOP
return next l_value;
END LOOP;
end;
$$
LANGUAGE plpgsql;
Я не уверен, что вы в курсе, но уже есть встроенная функция, которая выполняет то же самое: unnest()
.
Комментарии:
1. Спасибо за помощь 🙂 Мне тоже нужно приступить
EXECUTE... USING
к работе. Вы знаете, сEXECUTE... USING
чем проблема в моем коде?2. Обновление: это из-за
WINDOW
ключевого слова. Это работает после того, как я изменил имя переменной.