2013-05-20 26 views
5

構建具有各種WHERE條件的sql的最佳方式是什麼? 我的解決方案看起來醜陋:更優雅的方式來構建SQL添加WHERE並使用佔位符

my ($where, @values); 
if ($phone_number) 
{ 
    $where = 'AND pnone_number=?'; 
    @values = ($from, $till, $phone_number); 
} 
else 
{ 
    $where = ''; 
    @values = ($from, $till); 
} 
my $sql = 'SELECT * FROM calls WHERE time between ? AND ? '.$where.' ORDER BY time'; 
my $res = $dbh->selectall_arrayref($sql, undef, @values) or warn 'error'; 
+0

SQL ::設備將抽象掉在SQL Details。 – DavidO

回答

10

如何:

my $where = ''; 
my @values = ($from, $till); 

if ($phone_number) { 
    $where = 'AND phone_number=?'; 
    push @values, $phone_number; 
} 

,消除了您的else條款的必要性。

你也可以使用類似SQL::Abstract的東西。

use SQL::Abstract; 

... 

my ($sql, @values) = SQL::Abstract->new->select(
    'calls',             # table 
    '*',              # columns 
    { time => { '<=' => $till, '>' => $from },     # where clause 
     $phone_number ? (phone_number => $phone_number) : (), 
    }, 
    'time'              # order clause 
); 
+0

DBIx :: Class在底層使用了SQL :: Abstract。 '$ schema-> resultset('Calls') - > search({time => {-between,[$ from,$ until]},defined $ phone?(phone => $ phone):()},{order_by => {-asc =>'time'}}) - > all' – daxim

1

1=1的案件時加入$where將epmty。

my $where = "AND time between ? AND ? "; 
my @values = ($from, $till); 

if ($phone_number) { 
    $where .= 'AND pnone_number=? '; 
    push @values, $phone_number; 
} 

my $sql = 'SELECT * FROM calls WHERE 1=1 $where ORDER BY time'; 
my $res = $dbh->selectall_arrayref($sql, undef, @values) or warn 'error'; 
0

條件列表包括(又名"enterprise"):

my @values = ($from, 
       $till, 
       ($phone_number) x !! $phone_number, 
      ); 

my $sql = 'SELECT * FROM calls WHERE time between ? AND ? ' 
     . 'AND phone_number=?' x !! $phone_number 
     . ' ORDER BY time'; 
+1

'「enterprise」'可能適合打高爾夫球,但我不會使用它。 –

+3

這些是Perlship Enterprise的旅程,發現新的操作符和新的語法.... – friedo