有一个SQL SELECT查询,我如何获得项目数?

时间:2011-05-28 23:35:08

标签: perl sqlite dbi

我正在使用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或暗示我应该阅读的内容都将受到赞赏。

//我知道使用字符串连接查询是不好的

4 个答案:

答案 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 ...

现在,行计数将是结果集每行的第一列,因此只需在显示数据之前将其弹出。