2012-05-18 27 views
2

我正在編寫一個shell腳本來在postgres中運行一堆查詢。如何從shell腳本執行sql查詢

這是我寫的腳本。

#!/bin/sh 
host="172.16.7.102" 
username="priyank" 
dbname="truaxis" 
x=1 
echo "Connection done" 
while [ $x -le 3 ] 
do 
     x=$(($x + 1)) 
     echo "Connection $x" 
     psql -h $host $dbname $username << EOF 
     select * from students where sid = $x; 
     EOF 
done 

這個腳本有兩個問題。

  1. pgtest1.sh:17:語法錯誤:文件意外結束(預計 「完成」)

  2. 我如何通過$ X在SQL動態

我想每次迭代創建新的數據庫連接。

我對postgre和shell都是新手。

感謝

Priyank

回答

1

1) pgtest1.sh: 17: Syntax error: end of file unexpected (expecting "done")

你需要有EOF在自己的路線單獨(無空間等)

 psql -h $host $dbname $username << EOF 
     select * from students where sid = $x; 
EOF 

2) how do I pass $x in the sql dynamically

$ sh scriptname.sh value_of_x 

然後在你的腳本

x=$1 
0

EOF您指定的方式不能縮進。你需要做以下(注意儀表之前在這裏-doc的令牌:

while [ $x -le 3 ] ; do 
    psql foo bar <<-EOQ 
     select * from students where sid = $x; 
    EOQ 
done 

作爲一個側面說明,爲什麼不使用for循環,而不是while

for ((x=$1 ; x<=3 ; x++)) ; do 
    foo 
done 
0

我?除了我的情況,它是用於mysql的,我使用的是zsh。我設置了一個別名,以便shell不會做任何通配當我調用腳本,這樣我可以做到這一點:

$ sql select * from Table 

代替:

$ sql select '*' from Table 

別名是:

alias sql='noglob sql' 

我也用sed,自動將添加引用必要,這樣我可以做到這一點:

而不是210

$ sql select '*' from Client where first_name like "'John%'" and last_name = "'Wiley'" 

在我不想shell腳本,自動將添加引用我之前和=運算符這樣的省略之後的空間的情況下:

$ sql select t1.col1,t2.col2 from Table1 t1 join Table t2 on t1.client_id=t2.client_id. 

我在這裏粘貼劇本,以防你可能從中獲利。它是zsh和mysql特有的。您必須對其進行修改以適應您將sql命令傳遞到psql中的方式。腳本中使用的mpager程序是另一個shell腳本,它調用vim並要求它像一個適合瀏覽表格輸出的尋呼機:

#!/usr/bin/zsh 

function usage() { 
    echo -n "Usage: $0 [-h] [-t] [-d db] [-q] [-v] [-n] [p] [-q] [sql commands] 
    -d db Use specified database instead of the default one 
    -t  Do not 'tabularize' (borders) the output 
    -v  Be verbose 
    -n  Dry-run - show what command to be executed 
    -p  Pipe output to mpager 
    -q  Surpress own output, only show output from mysql 
    -h  Show this help message 
" 
} 

password=${DB_PASS:-secret} 
db=${DB:-default_db} 
user=${DB_USER:-username} 

USE_TABLE='--table' 
while getopts d:tvnhpq o 
do 
    case "$o" in 
    d) db=$OPTARG ;; 
    t) USE_TABLE='' ;; 
    v) verbose=1 ;; 
    n) dry_run='echo' ;; 
    p) use_mpager=t ;; 
    h) usage; exit 0 ;; 
    q) quiet=1;; 
    *) usage; 
     exit 1 ;; 
    esac 
done 
shift `expr $OPTIND - 1` 

case $2 in 
    database|databases) 
    db= 
    ;; 
esac 
if [ -z "$quiet" -a -n "$db" ]; then 
    echo 1>&2 "Database: $db" 
fi 

if [ $# -lt 1 ]; then 
    mysql --table -u $user -p$password $db "[email protected]" 
    exit 
fi 

to_run=`echo $*|sed -e "s/ \(=\|like\) *\([^'][^ ]*\+\)/ \1 '\2'/g"` 

# This helps for debugging. Show what is going to run when output is going to a 
# terminal: 
if [ -t 1 ]; then 
    echo "to_run: $to_run" 1>&2 
fi 

if [ -n "$verbose" ]; then 
    echo "mysql $USE_TABLE -u $user -p$password $db -e ${(q)to_run}" 
fi 
if [ -n "$use_mpager" ]; then 
    $dry_run mysql $USE_TABLE -u $user -p$password $db -e "$to_run" | mpager 
else 
    $dry_run mysql $USE_TABLE -u $user -p$password $db -e "$to_run" 
fi