Настройка
Искате да създавате задействания (многократно?), като използвате същата функция за задействане, както е посочено в моя свързан отговор на dba.SE . Трябва да подадете стойности към тригерната функция, за да създадете множество редове с множество стойности на колони, оттук и двумерният масив. (Но можем да работим с всеки ясно дефиниран низ!)
Единственият начин за предаване на стойности към функция за задействане на PL/pgSQL (различен от стойностите на колона на задействащия ред) е текст
параметри, които са достъпни във функцията като 0- базиран масив от текст в специалната променлива на масива TG_ARGV[]
. Можете да подадете променлив брой параметри, но по-рано обсъдихме един низов литерал, представляващ вашия двуизмерен масив.
Входът идва от двумерен масив на Python с цело число със знак числа, които се вписват в типа integer
на Postgres . Използвайте Postgres тип bigint
за покриване на цели числа без знак, като коментира
.
Текстовото представяне в Python изглежда така:
[[1,2],[3,4]]
Синтаксис за литерал на масив на Postgres:
{{1,2},{3,4}}
И искате да автоматизирате процеса.
Пълна автоматизация
Можете да свържете низа за CREATE TRIGGER
оператор във вашия клиент или можете да запазите логиката във функция от страна на сървъра и просто да подадете параметри.
Демонстриране на примерна функция, която взема име на таблица и низ, който е предаден на тригерната функция. Задействащата функция insaft_function()
е дефиниран в предишния ви въпрос на dba.SE
.
CREATE OR REPLACE FUNCTION f_create_my_trigger(_tbl regclass, _arg0 text)
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE format($$
DROP TRIGGER IF EXISTS insaft_%1$s_ids ON %1$s;
CREATE TRIGGER insaft_%1$s_ids
AFTER INSERT ON %1$s
FOR EACH ROW EXECUTE PROCEDURE insaft_function(%2$L)$$
, _tbl
, translate(_arg0, '[]', '{}')
);
END
$func$;
Обаждане:
SELECT f_create_my_trigger('measurements', '[[1,2],[3,4]]');
Или:
SELECT f_create_my_trigger('some_other_table', '{{5,6},{7,8}}');
Сега можете да подадете или [[1,2],[3,4]]
(с квадратни скоби) или {{1,2},{3,4}}
(с фигурни скоби). И двете работят еднакво. translate(_arg0, '[]', '{}'
трансформира първата във втора форма.
Тази функция премахва тригер със същото име, ако съществува, преди да създаде новия. Може да искате да премахнете или запазите този ред:
DROP TRIGGER IF EXISTS insaft_%1$s_ids ON %1$s;
Това се изпълнява с привилегиите на извикващата DB роля. Можете да го накарате да работи с привилегии на суперпотребител (или други), ако е необходимо. Вижте:
Има много начини да постигнете това. Зависи от точните изисквания.
Обяснение на format()код>
format()
и типът данни regclass
помагат за безопасното свързване на DDL командата и правят невъзможно SQL инжектирането. Вижте:
Първият аргумент е "форматният низ", следван от аргументите, които трябва да бъдат вградени в низа. Използвам долар-котиране
, което не е строго необходимо за примера, но като цяло е добра идея за свързване на дълги низове, съдържащи единични кавички:$$DROP TRIGGER ... $$
format()
се моделира по C функцията sprintf
. %1$s
е спецификатор на формат на формат( )
функция. Това означава, че първият (1$
) аргумент след форматиращия низ се вмъква като низ без кавички (%s
), следователно:%1$s
. Първият аргумент за форматиране е _tbl
в примера - regclass
параметърът се изобразява като легален идентификатор автоматично, в двойни кавички, ако е необходимо, така че format()
не трябва да прави повече. Следователно само %s
, а не %I
(идентификатор). Прочетете свързания отговор по-горе за подробности.
Другият използван спецификатор на формат е %2$L
:Втори аргумент като цитиран низов литерал .
Ако не сте запознати с format()
, поиграйте с тези прости примери, за да разберете:
SELECT format('input -->|%s|<-- here', '[1,2]')
, format('input -->|%s|<-- here', translate('[1,2]', '[]', '{}'))
, format('input -->|%L|<-- here', translate('[1,2]', '[]', '{}'))
, format('input -->|%I|<-- here', translate('[1,2]', '[]', '{}'));