首页 > 解决方案 > 是否可以在 psql 中结合使用 `-c` 和 `-v`?

问题描述

抽象的

为什么这不起作用:

$ psql -X -h localhost -d mydatabase -U postgres -v myschema=foo -c "SELECT :'myschema';"
ERROR:  syntax error at or near ":"
LINE 1: SELECT :'myschema';
               ^

但这按预期工作:

$ psql -X -h localhost -d mydatabase -U postgres -v myschema=foo

mydatabase=# SELECT :'myschema';
 ?column? 
----------
 foo
(1 row)

是否可以在通话-c中结合使用。-vpsql

语境

我正在尝试使用 bash 脚本执行DO这个)PostgreSQL 语句psql -c,我想将其中一个WHERE条件作为psql 变量传递

像这样的东西:

SCHEMA='foo'

! read -d '' sql_query << "EOF"
DO
$func$
BEGIN
   -- RAISE NOTICE '%', 
   EXECUTE
   (SELECT 'TRUNCATE TABLE ' || string_agg(oid::regclass::text, ', ') || ' CASCADE'
    FROM   pg_class
    WHERE  relkind = 'r'  -- only tables
    AND    relnamespace = :'myschema'::regnamespace
   );
END
$func$;    
EOF

psql -h localhost -U postgres -d mydatabase -v myschema="${SCHEMA}" -c "${sql_query}"

但它失败了:

ERROR:  syntax error at or near ":"
LINE 9:     AND    relnamespace = :'myschema'::regnamespace

尝试调试问题我只写了这个简单的查询:

psql -v myschema=foo -h localhost -d mydatabase -U postgres -c "SELECT :myschema;"
ERROR:  42601: syntax error at or near ":"
LINE 1: SELECT :myschema
               ^
LOCATION:  scanner_yyerror, scan.l:1087

或它的变体,如:

psql -v myschema="'foo'" -h localhost -d mydatabase -U postgres -c "SELECT :myschema;"
psql -v myschema 'foo' -h localhost -d mydatabase -U postgres -c "SELECT :myschema;"
psql -v myschema=foo -h localhost -d mydatabase -U postgres -c "SELECT :'myschema';"

两者都不起作用。

所以问题是。可以在通话-c中结合使用。-vpsql

DO 语句和 psql 变量

感谢评论,我发现混合语句和 psql 变量需要一种解决方法。DO

或者在bash水平上修复它。这就是我的做法:

SCHEMA='foo'

! read -d '' sql_query << EOF
DO
$func$
BEGIN
   -- RAISE NOTICE '%', 
   EXECUTE
   (SELECT 'TRUNCATE TABLE ' || string_agg(oid::regclass::text, ', ') || ' CASCADE'
    FROM   pg_class
    WHERE  relkind = 'r'  -- only tables
    AND    relnamespace = '${SCHEMA}'::regnamespace
   );
END
$func$;    
EOF

psql -h localhost -U postgres -d mydatabase -c "${sql_query}"

但问题仍然是如何(如果可能) psql 变量可以与-c

标签: bashpostgresqlpsql

解决方案


所以问题是。可以在 psql 调用中组合 -c 和 -v 。

不,psql 不会扩展命令行上传递的查询中的变量。它通过下面粗体概述的位在文档中暗示:

-c 命令
--command=命令

指定 psql 将执行给定的命令字符串 command。可以使用 -f 选项以任何顺序重复和组合此选项。当指定 -c 或 -f 时,psql 不会从标准输入读取命令;相反,它会在依次处理完所有 -c 和 -f 选项后终止。

command 必须是服务器完全可解析的命令字符串(即,它不包含特定于 psql 的功能),或者是单个反斜杠命令。


推荐阅读