0

我正在尝试在 bash 脚本中运行多个 sql 语句。我尝试在 psql 上运行以下语句,它工作正常。但是,当我在脚本上运行确切的语句时,它说该列不存在。

该声明

\copy (SELECT * FROM table_a h JOIN table_b b ON h."IDX" = b."IDX" WHERE b."XXX" BETWEEN 0 AND 100) to 'D:\$path\onetry1.csv' with csv HEADER;

我知道在 Postgres 中,需要在大写列名上使用双引号。我这样做了。

这是我的 bash 脚本:

#! /bin/sh

db="usm"

PGPASSWORD=XXX123 psql -h localhost -U postgres -d $db -c "\copy (SELECT * FROM table_a h JOIN table_b b ON h."IDX" = b."IDX" WHERE b."XXX" BETWEEN 0 AND 500) to '$path\onetry2.csv' with csv HEADER;"

我得到的错误:

错误:列 h.idx 不存在第 1 行:...M table_a h JOIN table_b b ON h.IDX = b....

4

2 回答 2

1

您的 shell 脚本不发送双引号。你有这个:

"\copy (SELECT * FROM table_a h JOIN table_b b ON h."IDX" = b."IDX" WHERE b."XXX" BETWEEN 0 AND 500) to '$path\onetry2.csv' with csv HEADER;"

它本质上是以下字符串的串联

"\copy (SELECT * FROM table_a h JOIN table_b b ON h."
IDX
" = b."
IDX
" WHERE b."
XXX
" BETWEEN 0 AND 500) to '$path\onetry2.csv' with csv HEADER;"

但是 PostgreSQL 永远不会看到双引号。使用反斜杠转义嵌套的双引号:

"\copy (SELECT * FROM table_a h JOIN table_b b ON h.\"IDX\" = b.\"IDX\" WHERE b.\"XXX\" BETWEEN 0 AND 500) to '$path\onetry2.csv' with csv HEADER;"

此外,更愿意避免强制使用所有大写字母或任何特定大小写。如果需要,您仍然可以输入大写字母。我只使用引用的列名来格式化最终查询更漂亮。

于 2019-11-09T05:15:45.777 回答
0

对于程序接受可能与 shell 进程冲突的输入的情况(例如,引号、双引号和各种替换),通常最好使用其他引用选项之一:

  • 如果程序可以处理 STDIN,<<word则可以使用此处的文档 ( )。
  • 如果程序只使用命令行参数,这里的文档可以内联
  • 考虑使用变量来简化引用。

我相信 psql 也将标准输入作为输入,所以这里的文档可以工作(删除 -c)。更容易格式化 SQL 以提高可读性。

PGPASSWORD=XXX123 psql -h localhost -U postgres -d $db <<SQL
\copy (
   SELECT *
   FROM table_a h
   JOIN table_b b ON h."IDX" = b."IDX"
   WHERE b."XXX" BETWEEN 0 AND 500)
   to '$path\onetry2.csv' with csv HEADER;
SQL

如果程序只接受命令行参数,here strings则可以使用(注意这是 bash 唯一的功能,而不是 POSIX)。

PGPASSWORD=XXX123 psql -h localhost -U postgres -d $db -c "$(cat <<SQL
\copy (
   SELECT *
   FROM table_a h
   JOIN table_b b ON h."IDX" = b."IDX"
   WHERE b."XXX" BETWEEN 0 AND 500)
   to '$path\onetry2.csv' with csv HEADER;
SQL
)

如果命令由变量构造(或可以存储在变量中),则可以消除复杂的引用。

V=$(cat <<SQL
\copy (
   SELECT *
   ...
   to '$path\onetry2.csv' with csv HEADER;
SQL
)
PGPASSWORD=XXX123 psql -h localhost -U postgres -d $db -c "$v"
于 2019-11-09T06:11:22.393 回答