You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本循环数组执行PostgreSQL查询导出失败求助

解决Bash循环结合psql HERE文档的执行问题

你遇到的核心问题是把Bash的循环逻辑放到了PostgreSQL的HERE文档(EOF块)内部——psql只识别SQL和自身的元命令(比如\COPY),完全看不懂Bash的declare、for这些语法,所以整个脚本执行时会报错,循环自然无法正常运行。当你移除循环语句后,剩下的是纯psql可识别的命令,所以能正常工作。

下面是修正后的脚本,同时我会标注几个关键的修改点:

dbname="XXX"
username="XXXXX"

# 修正Bash数组的写法:元素之间用空格分隔,不需要逗号
declare -a arr=('MFR' 'PQR' 'REV')

# 把循环逻辑放在HERE文档外部,由Bash处理迭代
for i in "${arr[@]}"
do
  psql "$dbname" "$username" << EOF
\COPY (
  SELECT 
    d.woyhh, 
    COALESCE(ct.ct, 0) AS total_count 
  FROM (
    SELECT f_woyhh(d::TIMESTAMP) AS woyhh 
    FROM generate_series(TIMESTAMP '2018-01-01', TIMESTAMP '2018-12-31', interval '1 hour') d
  ) d 
  LEFT JOIN (
    SELECT 
      f_woyhh((TIME)::TIMESTAMP) AS woyhh, 
      count(*) AS ct 
    FROM counties c 
    JOIN ltg_data d ON ST_contains(c.the_geom, d.ltg_geom) 
    WHERE cwa = '$i'  -- 用单引号包裹变量,符合SQL字符串语法要求
    GROUP BY 1
  ) ct USING (woyhh)  -- 修正了原查询中的笔误:whh → woyhh
  ORDER BY 1
) TO '/var/www/html/GIS/ltg_db/bigquery/hourly_$i.csv' CSV HEADER;
EOF
done

关键修改说明:

  • Bash数组语法修正:原数组写法里的逗号是多余的,Bash数组元素之间直接用空格分隔即可,否则会把逗号当成元素的一部分,导致查询时cwa值错误。
  • 循环逻辑移至外部:让Bash负责遍历数组,每次迭代生成独立的psql调用,这样变量$i会被Bash正确替换为当前的地理区域代码,再传递给psql执行。
  • SQL字符串变量包裹:WHERE cwa = '$i'中的单引号必须保留,因为cwa是字符串类型字段,没有单引号会触发SQL语法错误,同时也能避免简单的SQL注入风险。
  • 修复查询笔误:原查询中USING (whh)是错误的,应该和前面的woyhh列名保持一致,否则会因列名不匹配导致查询失败。
  • 导出路径加单引号:把CSV文件路径用单引号包裹,避免路径中如果出现特殊字符(比如空格)时出现解析错误。

这样修改后,脚本会逐个处理每个地理区域,执行对应的查询并导出到命名正确的CSV文件中,循环可以正常工作。

内容的提问来源于stack exchange,提问作者user1610717

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:06:20