Имея запрос SQL SELECT, как я могу получить количество элементов? - PullRequest
1 голос
/ 29 мая 2011

Я пишу веб-приложение на Perl с использованием среды Dancer.База данных находится в sqlite, и я использую DBI для взаимодействия с базой данных.

Я в порядке с операторами выбора, но мне интересно, есть ли способ подсчета выбранных строк.

Например, у меня есть

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, но это выглядит неправильно и избыточно для меня.Я ищу более или менее общий, СУХОЙ и не слишком тяжелый способ сделать это для базы данных.

Любой взлом SQL или Perl или подсказка, о которой я должен прочитать, будет принята.

// Я знаю, что использование конкатенации строк для запросов - это плохо

Ответы [ 4 ]

5 голосов
/ 29 мая 2011

Вы должны сделать это сложным путем: один запрос, чтобы получить счетчик, и другой, чтобы получить желаемый фрагмент набора строк:

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 голос
/ 31 мая 2011

Не используйте сам sqlite, но может сработать следующее:

select * from table join (select count(*) from table);

Работает ли вышеперечисленное или нет, первое, что я ищу, это прокручиваемые курсоры, если вы собираетесь просматривать результаты -Я сомневаюсь, что у sqlite есть такие.Однако в DBI вы можете использовать fetchall_arrayref с max_rows для извлечения «страницы» за раз.Просто посмотрите пример в документации DBI под fetchall_arrayref - это что-то вроде этого:

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'
                 }
        };
1 голос
/ 29 мая 2011

Не слишком знаком с perl, но я предполагаю, что вы можете просто сохранить результат $content->fetchall_arrayref и получить счетчик из этого массива, прежде чем вы его напечатаете.

[править]

Что-то вроде

my $ref = $content->fetchall_arrayref;
my $count = scalar(@$ref);
0 голосов
/ 29 мая 2011

Если вы хотите узнать, сколько будет результатов, а также получить сами результаты в одном запросе, то получите счетчик в качестве нового значения:

SELECT COUNT(*) AS num_rows, * from Table WHERE ...

Теперь счетчик строк будет первым столбцом каждой строки в вашем наборе результатов, поэтому просто извлеките его, прежде чем представлять данные.

...