Функция Postgres с аргументом списка и предложением in

Как создать функцию, которая принимает в качестве аргумента параметр integer[] и выполняет запрос с предложением IN с этим параметром в цикле. В цикле я хочу выполнить следующий выбор и результат этого запроса, который я хотел бы вернуть.

что-то вроде этого:

CREATE OR REPLACE FUNCTION function_which_i_want(my_argument integer[]) RETURNS my_schema_and_table[] AS
$BODY$
DECLARE
result my_schema_and_table[];
BEGIN
FOR l IN SELECT * FROM table2 WHERE id in (my_argument) LOOP
SELECT * FROM my_schema_and_table;
END LOOP;
END;
...

Я хочу получить объединение каждого select в цикле. один огромный результат. Возможно ли это? Пожалуйста помочь.

2 ответов


CREATE OR REPLACE FUNCTION function_which_i_want(my_argument integer[])
RETURNS my_schema_and_table[] AS
$BODY$
DECLARE
result my_schema_and_table[];
BEGIN

for l in 
    select t.*
    from
        table2 t
        inner join
        unnest(my_argument) m(id) on m.id = t.id
loop
    SELECT * FROM my_schema_and_table;
END LOOP;
END;

функция PL/pgSQL

заполнив пробелы в вашем вопросе, это может выглядеть так:

CREATE OR REPLACE FUNCTION func1(_arr integer[])
  RETURNS SETOF target_table LANGUAGE plpgsql AS
$func$
DECLARE
    l record;
BEGIN

FOR l IN
    SELECT *
    FROM   lookup_table
    WHERE  some_id = ANY(_arr)
LOOP
    RETURN QUERY
    SELECT *
    FROM   target_table
    WHERE  link_id = l.link_id;
END LOOP;

END
$func$;
  • если вы хотите вернуть результат SELECT * FROM my_schema_and_table; вы должны идти обо всей этой функции по-другому. Объявите это как RETURNS SETOF target_table

  • если вы действительно хотите SET строк из своего target_table, а не массив?

  • переписать IN построить в = ANY(_arr). Это способ использовать параметр array напрямую. Внутренне PostgreSQL переписывает выражение IN в = ANY() в любом случае. Тест с EXPLAIN ANALYZE чтобы увидеть для себя.
    или используйте конструкцию с unnest() и присоединиться к результирующей таблице, как @Clodoaldo демонстрирует. Это быстрее с длинными массивами.

упростить до простой функции SQL

выше еще неостроумно надуманный. Упростите функцию SQL, делая то же самое:

CREATE OR REPLACE FUNCTION func2(_arr integer[])
  RETURNS SETOF target_table LANGUAGE sql AS
$func$
SELECT t.*
FROM   (SELECT unnest() AS some_id) x
JOIN   lookup_table l USING (some_id) 
JOIN   target_table t USING (link_id); -- assuming both tables have link_id
$func$

звоните:

SELECT * FROM func2('{21,31}'::int[]);