Svar
DO
förväntar sig en sträng bokstavlig med plpgsql-kod. Symboler ersätts inte inuti strängar i psql.
Du kan sammanfoga hela strängen till en psql-variabel och sedan kör det.
- Hur sammanfogar man psql-variabler?
Ganska flerradsformat är inte möjligt, eftersom (per dokumentation):
Men i alla fall kan argumenten för ett metakommando inte fortsätta bortom slutet av raden.
Enkelt exempel:
test=# \set value foo
test=# \set do 'BEGIN\n RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
test=# DO :'do';
NOTICE: v: foo
Ersätt radbrytningar med \n
(eller ta bort dem om du inte bryr dig om snyggt format). Baserat på denna anpassade kod:
DO
'
DECLARE
_val text;
_vals text[] := string_to_array(>>values<<, '','');
BEGIN
FOREACH _val IN ARRAY _vals
LOOP
RAISE NOTICE ''v: %'', _val;
END LOOP;
END
'
Det ser ut så här:
test=# \set do 'DECLARE\n _val text;\n _vals text[] := string_to_array(' :'values' ', '','');\nBEGIN\n FOREACH _val IN ARRAY _vals\n LOOP\n RAISE NOTICE ''v: %'', _val;\n END LOOP;\nEND'
test=# DO :'do';
NOTICE: v: foo
NOTICE: v: bar
NOTICE: v: baz
DO
Jag lade till fet betoning på variabeln för att göra den lättare att upptäcka.
Relaterat svar från @Pavel (ab) med hjälp av en serversessionsvariabel:
- Refererar till sessionsvariabler (\set var='value') från PL/PGSQL
Alternativa lösningar
Förberett uttalande
Din nuvarande lösning ser inte så illa ut. Jag skulle förenkla:
PREPARE get_values AS SELECT * FROM regexp_split_to_table(:'values', ',');
DO
$do$
DECLARE
_val text;
BEGIN
FOR _val IN EXECUTE
'EXECUTE get_values'
LOOP
RAISE NOTICE 'v: %', _val;
END LOOP;
END
$do$;
Tillfälligt bord
Liknande lösning med en tillfällig tabell:
CREATE TEMP TABLE tmp AS SELECT * FROM regexp_split_to_table(:'values', ',') v;
DO
$do$
DECLARE
_val text;
BEGIN
FOR _val IN
TABLE tmp
LOOP
RAISE NOTICE 'v: %', _val;
END LOOP;
END
$do$;