我想在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...
将不会在带引号的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'
将文件路径和连接参数更改为您的设置。
旁边:postgresql-9.2,认真吗?自2017年以来不受支持。Consider upgrading to a current version.