通过Bash脚本执行PostgreSQL语句时提示列不存在问题
解决Bash脚本中psql执行\copy时大写列名报错的问题
你遇到的核心问题是Bash会解析你字符串里的双引号,导致传给PostgreSQL的SQL语句丢失了包裹大写列名的双引号——PostgreSQL默认会把未加双引号的标识符转成小写,所以才会提示column h.idx does not exist。
解决方案1:用单引号包裹整个SQL命令(推荐)
把-c后面的内容用单引号包裹,这样Bash不会解析里面的双引号;如果需要引用Bash变量(比如$path),可以把单引号拆开,变量部分用双引号包裹来实现变量展开:
#! /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;'
另外注意:Bash里路径最好用正斜杠/代替反斜杠\(反斜杠在Bash中是转义字符,容易出问题),所以把$path\onetry2.csv改成$path/onetry2.csv会更稳妥。
解决方案2:转义SQL中的双引号
如果你更习惯用双引号包裹整个-c参数,可以把SQL里的双引号用反斜杠\转义,让Bash把双引号原样传给psql:
#! /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;"
原理说明
在psql终端里直接执行时,终端不会解析你输入的双引号,所以PostgreSQL能正确识别"IDX"这个大写列名;但在Bash脚本中,双引号属于Bash的语法符号,会被Bash解析并移除,导致传给PostgreSQL的变成h.IDX,PostgreSQL自动转为小写h.idx,而你的列名是大写的IDX,所以就会报错找不到列。
内容的提问来源于stack exchange,提问作者dee
相关产品推荐
相关产品推荐

