Функция 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[]);