【问题标题】:more elegant way to construct SQL adding WHERE and using placeholders更优雅的方式来构造 SQL 添加 WHERE 和使用占位符
【发布时间】:2013-05-20 07:57:36
【问题描述】:

用不同数量的 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';

【问题讨论】:

  • SQL::Maker 会抽象出 SQL 细节。

标签: perl dbi


【解决方案1】:

怎么样:

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

【讨论】:

  • DBIx::Class 在底层使用 SQL::Abstract。 $schema-&gt;resultset('Calls')-&gt;search({ time =&gt; {-between, [$from, $until]}, defined $phone ? (phone =&gt; $phone) : () }, { order_by =&gt; {-asc =&gt; 'time'} } )-&gt;all
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    条件列表包含(又名"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';
    

    【讨论】:

    • "enterprise" 可能看起来很适合打高尔夫球,但我不会使用它。
    • 这些是 Perlship Enterprise 的航行,发现新的操作符和新的语法......
    猜你喜欢
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    相关资源
    最近更新 更多