PL/pgSQL Массив строк

Возможно ли следующее?
Я хочу иметь процедуру, написанную на PL/pgSQL, которая принимает в качестве параметра что-то вроде "коллекции строк", я имею в виду, что мне нужно передать функции словарную структуру:

Псевдокод:

function_name({key1:val1,key2:val2, key3:val3 [, ...] })

person biera    schedule 09.03.2012    source источник


Ответы (3)


С современным PostgreSQL такую ​​функцию можно упростить.
Тестовая установка:

CREATE TABLE tbl1 (id int, value text);

В этом случае нет необходимости создавать тип явно (если тип основан на строке таблицы), он создается для каждой таблицы неявно.
Функция:

CREATE FUNCTION f_insert_rows_into_tbl1(tbl1[])
  RETURNS VOID AS
$BODY$
    INSERT INTO tbl1 (id,value)
    SELECT (a).*
    FROM   (SELECT unnest($1) AS a) x;
$BODY$ LANGUAGE sql;

Вызов:

SELECT f_insert_rows_into_tbl1('{"(1,foo)","(2,bar)"}');

Обратите внимание на синтаксис ввода для массива строк!

person Erwin Brandstetter    schedule 09.03.2012

Посетите этот сайт http://postgres.cz/wiki/PostgreSQL_SQL_Tricks и найдите Array to table. В более новых версиях могут быть другие способы, но я некоторое время назад держал это в своих закладках. Источник с сайта:

CREATE OR REPLACE FUNCTION unpack(anyarray)
RETURNS SETOF anyelement AS $$ 
SELECT $1[i] 
   FROM generate_series(array_lower($1,1), 
                        array_upper($1,1)) g(i);
$$ LANGUAGE sql STRICT IMMUTABLE;

select unpack(array['a','b','c']);
person Kuberchaun    schedule 09.03.2012

Я думаю, вы можете использовать составной аргумент типа и массива. Что-то вроде (не проверено):

create type keyvalue as (
  key text,
  value text
);

create function function_name(keyvalue[]) returns null as $$
declare
  keyvalue x;
begin
  foreach x in array $1 loop
    insert into tablename(key,value) values (x.key, x.value);
  end loop
end;
$$ language plpgsql;

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

Использование unpack(), упомянутого JustBob, позволит не использовать цикл, что не очень похоже на SQL, а рассматривать этот массив как множество.

person Tometzky    schedule 09.03.2012
comment
Непроверенные решения бесполезны. Пожалуйста, попробуйте протестировать перед публикацией. - person Tim; 26.05.2020