2012-05-18 6 views
2

postgres에서 많은 쿼리를 실행하는 쉘 스크립트를 작성하고 있습니다.쉘 스크립트에서 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. 내가 SQL에서 $ X를 전달 어떻게 동적으로

내가 원하는 반복마다 새로운 db 연결을 생성합니다.

저는 Postgre 및 셸에 익숙하지 않습니다.

감사

Priyank는

답변

1

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

당신은 스크립트

에서 다음

 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 

(공간 등없이) 혼자 한 줄에 EOF가 필요

x=$1 
0

EOF 지정한 방식대로 들여 쓰기 할 수 없습니다. ? 왜 대신 while

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

I의 for 루프를 사용하지 보조 노트로

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

: 당신은 전에 여기-문서 토큰에 대시주의 (다음 작업을 수행 할 필요가 내 경우를 제외하고는 mysql을 위해 동일하다. 나는 zsh를 사용하고있다.대신

$ sql select * from Table 

: 나는 스크립트를 호출 할 때 나는이 할 수 있도록 쉘이 어떤 대체 (globbing)을하지 않도록 내가 별칭을 설정

$ sql select '*' from Table 

별명입니다 :

: 나는이 작업을 수행 할 수 있도록
alias sql='noglob sql' 

또한 자동적으로 필요한 경우 인용 추가 sed를 사용 (210)

대신 :

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

: 나는 쉘 스크립트가 자동적으로는 I 전과 같은 = 연산자 후 공간을 생략 인용을 추가하지 않는 경우

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

여기에서 대본을 붙여 넣으면서 이익을 얻을 수 있습니다. 그것은 zsh이고, mysql- 특정 적이다. psql에서 SQL 명령을 전달하는 방법에 맞게 수정해야합니다. 이 스크립트에 사용 된 mpager 프로그램은 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 
관련 문제