2016-11-22 150 views
0

我想編寫一個腳本,從文件中讀取行包含:在同一執行SQL查詢

  • SQL腳本的文件名,並
  • 一些SQL查詢行

並啓動查詢。

有一個list.txt文件的格式如下:

query.sql; set @var:='prod'; 

其中query.sql是SQL查詢文件,如:

select * 
    from db 
where [email protected] 

我想編寫一個執行的一個bash腳本像這樣的查詢:

mysql -uroot -proot -e 
    "set @var:='prod'; 
    select * 
     from db 
     where [email protected];" 

這是我試過的到目前爲止:

while read line; 
    do app=$(echo $line | awk '{for (i=2; i <= NF; i++) printf FS$i; print NL }'; 
    cat `echo $line | awk -F\; '{print $1}'`; echo ";"); 
    mysql -uroot -proot -e "`echo $app`" 
done < list.txt 

,但我有一個SQL錯誤,因爲shell不越獄以及在query.sql*字符。

調試我的代碼獲得:

$echo $app 
$set @var:='prod'; select a list.txt mysql query1.sql query.sql from db where [email protected] ; 

如何調整的代碼,以便有

$echo $app 
$set @var:='prod'; select * from db where [email protected] ; 

進一步詳情

有一個在awk命令loop,因爲文件list.txt可能包含多個查詢,如:

query.sql; set @var:='prod'; @a=asd; @b=zxc, @...=...; 
+0

我的錯誤,只是編輯了問題(這是我在服務器上的真實查詢) –

+0

@AlessandroBlasetti,你想要執行第二個SQL語句(在第一個';'之後),然後在第一個';',對嗎? –

+0

@RuslanOsmanov我想執行我的最後一行:'set @var:='prod'; select * from db where system = @ var;' –

回答

2

我不認爲你需要閱讀的SQL逐行掃描文件。假設有在文件名沒有分號,你可以用下面的命令AWK構造查詢:

awk -F\; '{ 
for (i = 2; i <= NF; i++) { 
    if ($i != "") printf("%s;", $i); 
} 
printf("source %s;\n", $1) 
}' list.txt | mysql -uroot -proot 

該命令使用;作爲一個字段分隔符。 for循環顯示從第二個開始的所有字段。最後的printf函數構建了一個查詢來源於SQL文件。

錯誤的原因

你的代碼沒有正確的SQL傳遞給MySQL客戶端,因爲這行:

mysql -uroot -proot -e "`echo $app`" 

外殼解釋$app變量中的特殊字符。特別是,*字符被擴展爲「當前目錄中的每個文件」。爲了防止解釋,使用quoting,即封閉變量在雙引號:"$app"

當引用一個變量,它通常建議用雙引號括它的名字。這可以防止的引用字符串中的所有特殊字符重新解釋 - 除了$,(反引號),並\(越獄)...

保持$爲雙引號內的特殊字符允許引用引用變量("$variable")也就是說,其值替換變量

而且,不需要子shell表達式(反引號和echo),如果你想獲得的變量值:

mysql -uroot -proot -e "$app" 
+0

'awk -F \; '{for(i = 2; i <= NF; i ++){if($ i!=「」)printf(「%s;」,$ i);} printf(「source%s; \ n」,$ 2 )}'list.txt' 給我 'set @var:='prod'; source set @var:='prod';' 而不是'set @var ...;查詢' –

+0

是的你是對的,我正在修改我自己的,它的工作原理! Great –

+0

爲了更好地理解bash腳本(我是新手),你知道我的代碼中哪個是問題嗎? –