2013-05-16 36 views
0

我寫了一個腳本,讓我傳遞(可選,我希望!)命令行參數並將它們發送到MySQL查詢。如果有任何被省略,我希望查詢基本上忽略該參數。如果我通過所有3,我的查詢正在工作。如果我通過第二個(整數)和第三個(一個字母)腳本也可以。但是,如果我省略了整數或字母,我就沒有結果。我的Perl腳本中有什麼失敗? MySQL/getopt

我試圖通過在我的MySQL查詢中使用ISNULL和Coalesce來解決這個問題,因爲我不確定聲明的變量是空還是空,如果我不明確地在我的命令行參數中傳遞它們。

目前,它的工作原理,如果我通過「Perl的Script.pl -s曲棍球-i 10-LH,或 「的Perl Script.pl -i 20 -lz」,但下的3個參數任何其他迭代的失敗。

我想知道的是 1.我是否可以按照我的意願選擇參數?我應該使用getopts而不是getopt嗎? 2.我需要在MySQL查詢中更改以使其工作爲我打算?爲什麼不是ISNULL或Coalesce正在工作? 3.我的傳遞或傳遞數據的方式有其他不正確的事嗎?

#!/usr/bin/perl -w 
use warnings; 
use DBI; 
use Getopt::Std; 
use strict; 

getopt('s:il'); 
our ($opt_s); 
our ($opt_i); 
our ($opt_l); 
my $sport_search; 
if ($opt_s) ($sport_search=$opt_s); 
my $integer_search; 
if ($opt_i=~m/\d+/) {$integer_search=$opt_i}; 
my $letter_search; 
if ($opt_l =~m/^[a-zA-Z]$/) {$letter_search=$opt_l}; 
my $g_hash = function1($sport_search,$integer_search,$letter_search); 
my $string = "Just a string!"; 
if (&function2($g_hash,$string) != 0) { 
    print "No values found for '$sport_search'","\n"; 
}; 

sub function1 { 

my ($lsport_search,$linteger_search,$lletter_search) = @_; 
our $dbh = DBI->connect{"dbi:mysql:dbname=database", "root", "password") 
or die $DBI::errstr; 
my $sql = "SELECT * from Players_Sport where Sport like '$lsport_search' AND length(Player)<=ISNULL('$linteger_search',20) AND Player between 'a' and ISNULL('lletter_search",'z')"; 
my $hash_ref = $dbh->selectall_hashref($sql, 'Player') 
or die $DBI::errstr; 
$dbh->disconnect 
    or warn "Disconnection failed: $DBI::errstr\n"; 
return $hash_ref; 
} 

sub function2 { 
my ($l_hash,$variable_two) = @_; 
my $hashvalue=(); 
if(keys $l_hash == 0) { 
    $hashvalue = -1; 
} 
    else {$hashvalue = 0; 
print "$_\n" for (keys %$l_hash); 
}; 
return $hashvalue; 
} 

回答

1

有在您的查詢的一些問題:

my $sql = "SELECT * from Players_Sport where Sport like '$lsport_search' 
    AND length(Player)<=ISNULL('$linteger_search',20) 
    AND Player between 'a' and ISNULL('lletter_search",'z')"; 

即使$ linteger_search和$ lletter_search在Perl的不確定,他們將永遠不會是SQL NULL,因爲你已經把他們周圍的報價。在MySQL中,''NULL不一樣。

你也有一些拼寫錯誤:'lletter_search"應該'$lletter_search'注意,你必須結束引用字符串與同類型,你與開始的引號的,但你開始用單引號和雙引號結束它(實際上,我很驚訝它沒有拋出SQL錯誤)。

在lletter_search之前,您還忘記了$變量前綴。

動態構建SQL字符串更爲常見,包括僅當搜索條件非空時才使用搜索條件。

my $sql = "SELECT * from Players_Sport where true "; 
if ($lsport_search) { 
    $sql .= " AND Sport like '$lsport_search' "; 
} 
if ($linteger_search) { 
    $sql .= " AND length(Player) <= $linteger_search"; 
} 
if ($lletter_search) { 
    $sql .= " AND Player between 'a' and '$lletter_search'"; 
} 
+0

謝謝你,很有趣。我會進行這些更改並檢查它。是否以非動態方式做我導致失敗的方式? – user2361820

+0

更好地使用綁定參數來保證正確性和安全性,不是嗎? (例如'... -s「Bill O'Karwin」')如下所示:'if($ x){$ sql。=「AND col like?」;推@params,$ x; } ... $ dbh-> selectall_hashref($ sql,'Player',{},@params)' – pilcrow

+0

@picrow,是的,我同意參數更好,但一次只能做一件事。 :-) –