更优雅的方法来构造添加WHERE和使用占位符的SQL

时间:2013-05-20 07:57:36

标签: perl dbi

用不同数量的WHERE条件构造sql的最佳方法是什么? 我的解决方案看起来很难看:

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';

3 个答案:

答案 0 :(得分: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
);

答案 1 :(得分:1)

1=1是为$where为空的情况添加的。

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';

答案 2 :(得分: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';