如何将psql变量传递给PL / pgSQL代码的DECLARE部分?

问题描述 投票:1回答:1

我想在PostgreSQL的PL / pgSQL代码的声明部分中使用一个额外的var。

DO $ANONYMOUS_BLOCK$ declare
   user_c cursor is
   select username
   from   users
   where upper(:v1) in ('ALL',upper(component_id)) order by username;
begin
   /* data */
end $ANONYMOUS_BLOCK$;

Shell命令:

psql -f test.psql -v v1='SR'

我尝试了多种情况在上述函数中获得值'SR',但无法实现。

预期结果:

DO $ANONYMOUS_BLOCK$ declare
   user_c cursor is
   select username
   from   users
   where upper('SR') in ('ALL',upper(component_id)) order by username;
begin
   /* data */
end $ANONYMOUS_BLOCK$;

需要在v1处获得'SR'值。

我收到此错误:

psql:test.psql:13: ERROR:  syntax error at or near ":"
LINE 5:    where  :v1 in ('ALL',upper(component_id)) order by userna...
postgresql parameter-passing plpgsql psql postgresql-9.2
1个回答
0
投票

The manual for psql:

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

DO语句(或函数)的主体带引号的文字。在这种情况下,以美元报价,但都相同。

我在dba.SE的最新答案中也给出了相同的否定答复:

但是有多种解决方法,我在那里提供了一些解决方法。

一种适合您的情况的简单方法可能是创建临时函数而不是DO语句,然后立即调用它。然后,您可以轻松地传递变量。将此写入您的文件test.psql

CREATE FUNCTION pg_temp.foo(_v1 text)
  RETURNS void AS  -- can also return sth. (as opposed to DO)
$func$
DECLARE
   user_c cursor is
   SELECT username
   FROM   users
   WHERE  upper(_v1) IN ('ALL', upper(component_id))
   ORDER  BY username;
BEGIN
   RAISE NOTICE '%', _v1;  -- to demonstrate
   -- more
END 
$func$  LANGUAGE plpgsql;

SELECT pg_temp.foo(:'v1'); -- call with psql variable interpolation

然后从psql或直接从shell调用它:

Linux shell:

psql -f '\path\to\file\test.psql' -v v1='SR'

Windows shell:

"C:\Program Files\PostgreSQL\12\bin\psql" -p 5432 -U postgres -f "C:\path\to\file\test.psql" -v v1='SR'

将文件路径和连接参数更改为您的设置。

旁边:,认真吗?自2017年以来不受支持。Consider upgrading to a current version.

© www.soinside.com 2019 - 2024. All rights reserved.