Risposta
DO
si aspetta un letterale stringa con codice plpgsql. I simboli non vengono sostituiti all'interno di stringhe in psql.
Potresti concatenare l'intera stringa in una variabile psql e quindi eseguilo.
- Come concatenare le variabili psql?
Non è possibile un bel formato a più righe, perché (per documentazione):
Ma in ogni caso, gli argomenti di un meta-comando non possono continuare oltre la fine della linea.
Esempio semplice:
test=# \set value foo
test=# \set do 'BEGIN\n RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
test=# DO :'do';
NOTICE: v: foo
Sostituisci le interruzioni di riga con \n
(o rimuovili se non ti interessa un bel formato). Basato su questo codice adattato:
DO
'
DECLARE
_val text;
_vals text[] := string_to_array(>>values<<, '','');
BEGIN
FOREACH _val IN ARRAY _vals
LOOP
RAISE NOTICE ''v: %'', _val;
END LOOP;
END
'
Si presenta così:
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
Ho aggiunto grassetto enfasi sulla variabile per renderla più facile da individuare.
Risposta correlata di @Pavel (ab)utilizzando una variabile di sessione del server:
- Riferito a variabili di sessione (\set var='value') da PL/PGSQL
Soluzioni alternative
Dichiarazione preparata
La tua soluzione attuale non sembra così male. Semplificherei:
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$;
Tabella temporanea
Soluzione simile con una tabella temporanea:
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$;