我一直在阅读Perl Hacks书中的一些食谱。方法#24“在没有SQL的情况下动态查询数据库”看起来很有趣。我们的想法是使用SQL-Abstract为您生成SQL语句。
生成select语句的语法如下所示:
my($stmt, @bind) = $sql->select($table, \@fields, \%where, \@order);
为了进一步说明,一个例子看起来像这样(取自perldoc):
my %where = (
requestor => 'inna',
worker => ['nwiger', 'rcwe', 'sfz'],
status => { '!=', 'completed' }
);
my($stmt, @bind) = $sql->select('tickets', '*', \%where);
上面会给你这样的东西:
$stmt = "SELECT * FROM tickets WHERE
( requestor = ? ) AND ( status != ? )
AND ( worker = ? OR worker = ? OR worker = ? )";
@bind = ('inna', 'completed', 'nwiger', 'rcwe', 'sfz');
然后您可以在DBI代码中使用它,如下所示:
my $sth = $dbh->prepare($stmt);
$sth->execute(@bind);
现在,有时WHERE
子句中列的顺序非常重要,特别是如果要充分利用索引。
但是,由于SQL-Abstract中WHERE
子句生成器的列是通过散列指定的 - 并且众所周知,无法保证从perl散列中检索数据的顺序 - 你似乎失去了指定列顺序的能力。
我错过了什么吗?在使用SQL-Abstract时,是否有其他工具可以保证列在WHERE
子句中出现的顺序?
答案 0 :(得分:3)
我最初误解了你的问题。
您可以使用-and
来实现所需的排序。
例如:
#!/usr/bin/perl
use strict; use warnings;
use SQL::Abstract;
my $sql = SQL::Abstract->new;
my ($stmt, @bind) = $sql->select(
tickets => '*',
{
-and => [
requestor => 'inna',
status => { '!=', 'completed' },
worker => ['nwiger', 'rcwe', 'sfz'],
],
}
);
print "$stmt\n";
答案 1 :(得分:0)
这个模块无法完成所有工作 - 它可以方便地构建将在“大部分时间”完成工作的查询。有时您可能仍需要手动编写查询。我在我的主$ work :: app中使用SQL :: Abstract,并且从未遇到过您描述的情况。一个好的SQL引擎将知道哪些键被索引,并优化查询以便首先使用它们,无论您指定的顺序如何。您确定您的引擎不一样,并且您在查询中指定的顺序非常重要吗?
如果您确实需要以特殊顺序订购WHERE子句,您可能会发现更容易编写子查询。 SQL :: Abstract也可以使这更容易。