在线程here之后:我使用psql变量创建了以下SQL脚本:
--query.sql
select * from my_table
where day=:'day' and state in (:'states')
我在脚本中使用以下shell命令通过SSH执行上述SQL脚本:
#!/bin/sh
day='2015-05-01'
state='CA'
ssh myserver "psql -A -q -F $'\t' -d my_db -o temp_file.csv --set=day=${day} --set=states=${state}" < 'query.sql'
我遇到的问题是如何传递状态列表。如果我想从shell脚本传递3个状态,如:
state="'CA','NY','WA'"
我的数据库查询将返回0行。将状态列表从shell脚本传递到psql变量的正确方法是什么?
答案 0 :(得分:1)
问题似乎不在shell中,而是在SQL中:
state in (:'states')
在大多数SQL品种中 - 以及包含Postgres的AFAIK--变量是标量。它包含单个值,而不是列(当然不是行)。你想要一个列表,但在SQL中没有这样的动物。用
初始化时state="'CA','NY','WA'"
你提供的字符串看起来有点像列表。然而,SQL并没有被愚弄:它期望一个标量和口香糖就是它所看到的。由于没有具有该名称的状态,因此它返回零行。
传递状态列表的正确方法是什么
有三种常见的答案:糟糕的方式,好的方式和正确的方式。
不安全的方法是动态构造IN子句。
标准答案是将值作为列提供。您可能拥有表值变量或临时表。将状态名称插入一个,并执行类似
where state in ('select state from #states')
where state in ('select state from ... where ... = :criterion)
虽然我从未见过明确的理由,但我怀疑SQL中没有很好地支持任意列表,因为它们通常可以而且应该通过设计来避免。