我正在使用Dancer框架在Perl中编写一个Web应用程序。数据库是sqlite,我使用DBI进行数据库交互。
我对select语句很好,但我想知道有没有办法计算选定的行。
E.g。我有
get '/' => sub {
my $content = database->prepare(sprintf("SELECT * FROM content LIMIT %d",
$CONTNUM));
$content->execute;
print(Dumper($content->fetchall_arrayref));
};
如何在不发出其他查询的情况下计算结果中的所有项目?
我想以这种方式实现的目标是每页显示30个项目并知道会有多少页面。当然我可以运行SELECT COUNT(*)foo bar,但它看起来不对我而且多余。我正在寻找或多或少的一般,DRY,而不是太沉重的数据库方式这样做。
任何SQL或Perl hack或暗示我应该阅读的内容都将受到赞赏。
//我知道使用字符串连接查询是不好的
答案 0 :(得分:5)
你必须这么做:一个查询得到计数,另一个查询得到你想要的行集:
my $count = $database->prepare('SELECT COUNT(*) FROM content');
$count->execute();
my $n = $count->fetchall_arrayref()->[0][0];
my $content = $database->prepare('SELECT * FROM content LIMIT ?');
$content->execute($CONTNUM);
#...
答案 1 :(得分:1)
对perl不太熟悉,但我假设您可以存储$content->fetchall_arrayref
的结果,并在打印它时从该数组中检索计数。
[编辑]
像
这样的东西my $ref = $content->fetchall_arrayref;
my $count = scalar(@$ref);
答案 2 :(得分:1)
不要自己使用sqlite,但以下内容可能有效:
select * from table join (select count(*) from table);
无论上面是否有效,我要寻找的第一件事是可滚动游标,如果你要翻阅结果 - 我怀疑sqlite有那些。但是,在DBI中,您可以使用带有max_rows的fetchall_arrayref一次获取“页面”。只需在fetchall_arrayref下的DBI文档中查找示例 - 它是这样的:
my $rowcache = [];
while( my $row = ( shift(@$rowcache) || shift(@{$rowcache=$sth->fetchall_arrayref(undef,100)||[]}) )
) {
# do something here
}
更新:添加了selectall_hashref所获得的内容,假设该表被称为带有一个名为“a”的整数列的内容:
$ perl -le 'use DBI; my $h = DBI->connect("dbi:SQLite:dbname=fred.db"); my $r = $h->selectall_hashref(q/select * from content join (select count(*) as count from content)/, "a");use Data::Dumper;print Dumper($r);'
$VAR1 = {
'1' => {
'count' => '3',
'a' => '1'
},
'3' => {
'count' => '3',
'a' => '3'
},
'2' => {
'count' => '3',
'a' => '2'
}
};
答案 3 :(得分:0)
如果您想知道将会有多少结果,以及在一个查询中获取结果本身,那么将计数作为新值:
SELECT COUNT(*) AS num_rows, * from Table WHERE ...
现在,行计数将是结果集每行的第一列,因此只需在显示数据之前将其弹出。