Here's what I would like to do:
\set values foo,bar,baz
DO $$
DECLARE
value TEXT;
values TEXT[] := string_to_array(:'values', ',');
BEGIN
FOREACH value IN ARRAY values LOOP
raise notice 'v: %', value;
END LOOP;
END $$ LANGUAGE plpgsql;
Which results in the following error:
ERROR: syntax error at or near ":" SELECT string_to_array(:'values', ',') INTO values... ^
Here's the solution I have currently, but it feels hacky:
\set values foo,bar,baz
PREPARE get_values AS SELECT string_to_array(:'values', ',');
DO $$
DECLARE
value TEXT;
values TEXT[];
BEGIN
EXECUTE 'EXECUTE get_values' INTO values;
FOREACH value IN ARRAY values LOOP
raise notice 'v: %', value;
END LOOP;
END $$ LANGUAGE plpgsql;
Was able to take advantage of this solution:
Where I set the variable as such and retrieve it with
current_setting()
Answer
DO
expects a string literal with plpgsql code. Symbols are not substituted inside strings in psql.You could concatenate the whole string into a psql variable and then execute it.
Pretty multi-line format is not possible, because (per documentation):
Simple example:
Replace line breaks with
\n
(or remove them if you don't care for pretty format). Based on this adapted code:It looks like this:
I added bold emphasis to the variable to make it easier to spot.
Related answer by @Pavel (ab)using a server session variable:
Alternative solutions
Prepared statement
Your current solution doesn't look that bad. I would simplify:
Temporary table
Similar solution with a temporary table: