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

xoi*_*oid 5 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';
Run Code Online (Sandbox Code Playgroud)

fri*_*edo 10

怎么样:

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

if ( $phone_number ) { 
    $where = 'AND phone_number=?';
    push @values, $phone_number;
}
Run Code Online (Sandbox Code Playgroud)

这消除了对你的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
);
Run Code Online (Sandbox Code Playgroud)