Answer
DO http://www.postgresql.org/docs/current/interactive/sql-do.html期望一个字符串字面量与 plpgsql 代码。 psql 中的字符串内部不会替换符号。
您可以将整个字符串连接到 psql 变量中,然后then执行它。
- 如何连接psql变量? https://dba.stackexchange.com/a/21131/3684
漂亮的多行格式是不可能的,因为(根据文档 http://www.postgresql.org/docs/current/interactive/app-psql.html#APP-PSQL-META-COMMANDS):
但无论如何,元命令的参数不能继续下去
超出该线的末端。
简单的例子:
test=# \set value foo
test=# \set do 'BEGIN\n RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
test=# DO :'do';
NOTICE: v: foo
将换行符替换为\n
(或者如果您不喜欢漂亮的格式,请将它们删除)。基于此改编代码:
DO
'
DECLARE
_val text;
_vals text[] := string_to_array(>>values<<, '','');
BEGIN
FOREACH _val IN ARRAY _vals
LOOP
RAISE NOTICE ''v: %'', _val;
END LOOP;
END
'
它看起来像这样:
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
I added bold强调变量,以便更容易发现。
@Pavel (ab)使用的相关答案服务器会话变量 http://www.postgresql.org/docs/current/interactive/runtime-config-custom.html:
- 从 PL/PGSQL 引用会话变量 (\set var='value') https://stackoverflow.com/questions/28868514/referring-to-session-variables-set-var-value-from-pl-pgsql/28871424#28871424
替代解决方案
准备好的声明
您当前的解决方案看起来并没有那么糟糕。我会简化:
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$;
临时表
使用临时表的类似解决方案:
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$;