我必须使用BASH连接到我们的PostgreSQL 9.1数据库服务器以执行各种SQL语句。
由于反复打开/关闭太多数据库连接导致性能问题(现在,我们将每个语句发送到psql命令)。
我正在考虑使用命名管道维护一个SQL语句块的开放数据库连接的可能性。
我遇到的问题是,一旦打开连接并执行SQL语句,我就不知道何时停止从psql读取。我考虑过解析输出以寻找提示,虽然我不知道这是否安全,考虑到字符可能嵌入SELECT输出的可能性。
有人有建议吗?
这是我迄今为止所拥有的一个简化示例......
#!/bin/bash
PIPE_IN=/tmp/pipe.in
PIPE_OUT=/tmp/pipe.out
mkfifo $PIPE_IN $PIPE_OUT
psql -A -t jkim_edr_md_xxx_db < $PIPE_IN > $PIPE_OUT &
exec 5> $PIPE_IN; rm -f $PIPE_IN
exec 4< $PIPE_OUT; rm -f $PIPE_OUT
echo 'SELECT * FROM some_table' >&5
# unfortunately, this loop blocks
while read -u 4 LINE
do
echo LINE=$LINE
done
答案 0 :(得分:1)
使用--file=filename
进行批量执行。
根据您对流量控制的需求,您可能希望使用另一种语言,使用更灵活的DB API(Python将是我的选择,但使用任何有效的方法)。
答案 1 :(得分:0)
echo >&5 "SELECT * FROM some_table"
应该阅读
echo 'SELECT * FROM some_table' >&5
重定向运算符>&
位于echo
的参数之后;而且,如果你使用""
引号,一些标点符号可能会被shell专门处理,以后会导致犯规和神秘的错误。另一方面,引用'
将是......丑陋的。 SELECT * FROM some_table WHERE foo=\'Can\'\'t read\''
...
您可能还希望创建这些管道比/tmp
更安全。有一个很大的安全漏洞竞争条件,主机上的其他人可能会劫持你的连接。尝试使用/var/run/yournamehere/
权限创建0700
这样的文件夹,并在那里创建管道,理想情况下,PIPE_IN=/var/run/jinkimsqltool/sql.pipe.in.$$
- $$
这样的名称将是您的进程ID,因此同时执行脚本不会互相辱骂。 (为了加剧安全漏洞,管道不应该需要rm -rf
,但是聪明的破解者可以使用特权扩展来滥用-r
。只需rm -f
即可。)
答案 2 :(得分:0)
你可以使用
\o YOUR_PIPE
SELECT whatever;
\o
将打开,写入和关闭管道。你的BASH-fu看起来比我强很多,所以我会让你弄清楚细节:)