Svar
DO
forventer en streng literal med plpgsql-kode. Symboler erstattes ikke inde i strenge i psql.
Du kan sammenkæde hele strengen i en psql-variabel og derefter udføre det.
- Hvordan sammenkædes psql-variabler?
Temmelig multi-line format er ikke muligt, fordi (pr. dokumentation):
Men under alle omstændigheder kan argumenterne for en metakommando ikke fortsætte ud over slutningen af linjen.
Simpelt eksempel:
test=# \set value foo
test=# \set do 'BEGIN\n RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
test=# DO :'do';
NOTICE: v: foo
Erstat linjeskift med \n
(eller fjern dem, hvis du er ligeglad med smukt format). Baseret på denne tilpassede kode:
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 sådan ud:
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
Jeg tilføjede fed fremhævelse af variablen for at gøre den nemmere at få øje på.
Relateret svar fra @Pavel (ab) ved hjælp af en serversessionsvariabel:
- Hviserer til sessionsvariabler (\set var='value') fra PL/PGSQL
Alternative løsninger
Udarbejdet erklæring
Din nuværende løsning ser ikke så dårlig ud. Jeg vil forenkle:
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$;
Midlertidig tabel
Lignende løsning med en midlertidig tabel:
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$;