Antwort
DO
erwartet ein String-Literal mit plpgsql-Code. Symbole werden in Strings in psql nicht ersetzt.
Sie könnten den gesamten String in eine psql-Variable verketten und dann ausführen.
- Wie werden psql-Variablen verkettet?
Ziemlich mehrzeiliges Format ist nicht möglich, weil (laut Dokumentation):
Aber in jedem Fall können die Argumente eines Meta-Befehls nicht über das Ende der Zeile hinaus fortgesetzt werden.
Einfaches Beispiel:
test=# \set value foo
test=# \set do 'BEGIN\n RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
test=# DO :'do';
NOTICE: v: foo
Ersetzen Sie Zeilenumbrüche durch \n
(oder entfernen Sie sie, wenn Sie sich nicht für ein hübsches Format interessieren). Basierend auf diesem angepassten Code:
DO
'
DECLARE
_val text;
_vals text[] := string_to_array(>>values<<, '','');
BEGIN
FOREACH _val IN ARRAY _vals
LOOP
RAISE NOTICE ''v: %'', _val;
END LOOP;
END
'
Es sieht so aus:
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
Ich habe fett hinzugefügt Betonung auf die Variable, damit sie leichter zu erkennen ist.
Zugehörige Antwort von @Pavel (ab)unter Verwendung einer Serversitzungsvariablen:
- Verweise auf Sitzungsvariablen (\set var='value') von PL/PGSQL
Alternative Lösungen
Vorbereitete Erklärung
Deine jetzige Lösung sieht gar nicht so schlecht aus. Ich würde vereinfachen:
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$;
Temporäre Tabelle
Ähnliche Lösung mit einer temporären Tabelle:
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$;