Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use \set variable inside plpgsql declare block [duplicate]

My SQL script contains the following:

\set test 'some value'  
DO $$DECLARE  
  v_test text:= :'test';  
BEGIN  
  RAISE NOTICE 'test var is %',v_test;  
END$$;  

I get a syntax error when trying to evaluate the value of test:

ERROR:  syntax error at or near ":"  

Ideally I'd like to have an anonymous plpqsql block living in a file which will then get called from a shell script using a set of environment variables

like image 409
inabramova Avatar asked Jun 09 '16 01:06

inabramova


People also ask

How do I declare a variable in Plpgsql?

The general syntax of a variable declaration is: name [ CONSTANT ] type [ COLLATE collation_name ] [ NOT NULL ] [ { DEFAULT | := | = } expression ]; The DEFAULT clause, if given, specifies the initial value assigned to the variable when the block is entered.

Can we declare variable in begin block?

You can declare variables only in the DECLARE section of a block.

Can we use declare inside begin?

In general, yes you can, you just nest another execution block inside your current one...

Can you use variables in PostgreSQL?

In PostgreSQL, a variable is a meaningful name for a memory location. A variable holds a value that can be changed through the block or function. A variable is always associated with a particular data type. Before using a variable, you must declare it in the declaration section of the PostgreSQL Block.


1 Answers

The explanation is, according to the manual:

Variable interpolation will not be performed within quoted SQL literals and identifiers.

The body of the DO statement is a dollar-quoted string. So no interpolation inside the string.

Since it must be a literal string, you can also not concatenate strings on the fly. The manual:

This must be specified as a string literal, just as in CREATE FUNCTION.

But you can concatenate the string and then execute it.

\set [ name [ value [ ... ] ] ]

Sets the psql variable name to value, or if more than one value is given, to the concatenation of all of them.

Bold emphasis mine. You just have to get the quoting right:

test=# \set test 'some value'
test=# \set code 'DECLARE v_test text := ' :'test' '; BEGIN RAISE NOTICE ''test var is: %'', v_test; END'
test=# DO :'code';
NOTICE: test var is: some value
DO
test=#

But I would rather create a (temporary) function and pass the value as parameter (where psql interpolation works). Details in this related answer on dba.SE:

  • CREATE SEQUENCE using expressions with psql variables for parameters
like image 101
Erwin Brandstetter Avatar answered Oct 01 '22 05:10

Erwin Brandstetter