PostgreSQL PL / pgSQL синтаксическая ошибка с циклом FOREACH - PullRequest
0 голосов
/ 13 марта 2019

Я пытаюсь выучить 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 Ответ

1 голос
/ 13 марта 2019

Ваша функция объявлена ​​как returns void, поэтому вы не можете ничего от нее вернуть. Если вы хотите вернуть несколько значений, вам нужно использовать returns setof integer

Но у него больше проблем, чем у этого.

  1. вы должны дать своему параметру имя (не ошибка, а хороший стиль кодирования)
  2. чтобы вернуть значение из функции, которую вам нужно использовать return. Чтобы вернуть несколько значений (из-за returns setof), вам нужно использовать return next
  3. нет необходимости в динамическом SQL для возврата значения, вы можете вернуть переменную напрямую.
  4. Также не ошибка, но: 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().

...