在 plpgsql 声明块中使用 \set 变量

ina*_*ova 6 postgresql plpgsql psql

我的 SQL 脚本包含以下内容:

\set test 'some value'  
DO $$DECLARE  
  v_test text:= :'test';  
BEGIN  
  RAISE NOTICE 'test var is %',v_test;  
END$$;  
Run Code Online (Sandbox Code Playgroud)

尝试评估 test 的值时出现语法错误:

ERROR:  syntax error at or near ":"  
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望有一个匿名 plpqsql 块存在于一个文件中,然后使用一组环境变量从 shell 脚本中调用该块

Erw*_*ter 4

根据手册的解释是:

变量插值不会在带引号的 SQL 文字和标识符内执行。

语句的主体DO是一个(美元引用的)字符串。所以字符串内没有插值。

由于它必须是文字字符串,因此您也不能即时连接字符串。手册:

必须将其指定为字符串文字,就像在CREATE FUNCTION.

但您可以连接字符串然后执行它。

\set [ name [ value [ ... ] ] ]
Run Code Online (Sandbox Code Playgroud)

将 psql 变量名称设置为值,或者如果给出了多个值,则将其设置为所有值的串联。

大胆强调我的。你只需要正确引用:

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=#
Run Code Online (Sandbox Code Playgroud)

但我宁愿创建一个(临时)函数并将值作为参数传递(其中 psql 插值起作用)。dba.SE 上相关答案的详细信息: