I'm using psql to process a sql file.
A parameter is sent to the psql call as:
-v myVar=5
The SQL file needs to loop from 1
till myVar
and do some stuff. i
is a being declared as DECLARE i integer = 1;
I have tried the following syntax/s on the WHILE clause
WHILE i <= :myVar LOOP
and
WHILE i <= myVar LOOP
But psql is reporting
ERROR: syntax error at or near ":
LINE 6: WHILE i <= :myVar LOOP
^
and
ERROR: column "myVar " does not exist
LINE 1: i <= myVar
The whole loop is defined like this:
DO
$do$
DECLARE i integer = 1;
BEGIN
WHILE i <= :myVar LOOP
-- do some stuff with i
i := i + 1;
END LOOP;
END;
$do$
The problem is that the body of the DO
statement is a dollar-quoted string literal, and there is no variable substitution in string literals.
With psql
, you could use \gexec
:
SELECT format('DO
$do$
DECLARE i integer = 1;
BEGIN
WHILE i <= %L::integer LOOP
-- do some stuff with i
i := i + 1;
END LOOP;
END;
$do$', :myVar) \gexec
The %L
will be replaced with the (singly quoted) value of myVar
, and the result of the SELECT
statement (the DO
statement) will be executed.
I use %L
to get a string literal and cast it to integer
. The point of that seemingly useless exercise is to avoid problems with SQL injection.