Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 是否可以在psql中组合“-c”和“-v”?_Bash_Postgresql_Psql - Fatal编程技术网

Bash 是否可以在psql中组合“-c”和“-v”?

Bash 是否可以在psql中组合“-c”和“-v”?,bash,postgresql,psql,Bash,Postgresql,Psql,摘要 这不起作用的原因: $ 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 mys

摘要

这不起作用的原因:

$ 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)
是否可以在
psql
调用中组合
-c
-v

上下文

我正试图从bash脚本中执行一个带有
psql-c
DO
()PostgreSQL语句,其中我希望传递一个
where
条件作为

大概是这样的:

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}"
为了调试问题,我只编写了以下简单查询:

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';"
两者都不起作用

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

DO语句和psql变量

多亏了这些评论,我发现混合使用
DO
语句和psql变量是非常必要的

或者在
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}"
SCHEMA='foo'
! 已读-d''sql\u查询
所以问题是。可以在psql中组合-c和-v
打电话

不,psql不会在命令行上传递的查询中展开变量。 下面用粗体表示的位暗示了这一点:

-c命令
--命令

指定psql将执行给定的命令字符串command。此选项可以按任意顺序重复和组合 -f选项。当指定-c或-f时,psql不会读取 来自标准输入的命令;相反,它在处理后终止 所有-c和-f选项都按顺序显示

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


不。
do
body只是一个字符串(以美元报价),它按原样使用,没有psql变量替换。假设选择“foo:myschema bar”与
相同
选择$str$foo:myschema bar$str$只需使用bash变量替换即可。对于非
do
情况,如
psql-v myschema=foo-h localhost-d mydatabase-U postgres-c“SELECT:'myschema';”
,这是否回答了您的问题@谢谢你的研究。它回答了
DO
的具体用例,无论如何都可以通过转义美元报价或其他
bash
策略来解决,但仍然没有回答为什么简单的
选择:myschema使用
-c
查询不起作用。因为替换后将
选择foo(赋值变量时psql删除单引号)@另一个人已经提供了可能的解决方案。如果您想在字符串中使用变量,那么它应该类似于
选择'foo'| |:'myvar'| |'bar'哎哟。我真丢脸。我读了文件,但误解了(或未读)那一点信息。谢谢。
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}"