Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > простой цикл


Автор: kall1sto 27.3.2009, 15:18
Здравствуйте, возникла проблема. Работал у нас программист  он писал прогу: смысл - багтрекер... Он  уволился а мне (сисадмину)поручили с этим разобраться, а я в перле как ... ).
Вообщем через запрос перла о написал:
Код

#!/usr/bin/perl

use DBI;
use HTML::Entities;
my $dbh = DBI->connect ( 'dbi:SQLite:dbname=..\bugserver.db' );
my $sth = $dbh->prepare ( 'SELECT * FROM `reports` ORDER BY `id` DESC;' );
$sth->execute ();

print "Content-Type: text/html\n\n";
print "<html><body>\n";
print "<h1>Recent reports</h1>\n";

print "<table border=1>\n";

print "<tr><th>ID<th>Date<th>Version<th>Machine<th>Exception<th>Module<th>Function<th>Report file\n";

my @row_data;
while ( @row_data = $sth->fetchrow_array () )
{
    print "<tr>";
    print "<td>" . $row_data[0];
    print "<td>" . $row_data[1];
    print "<td>" . $row_data[2];
    print "<td>" . $row_data[3];
    print "<td>" . $row_data[5];
    print "<td>" . $row_data[6];
    print "<td>" . encode_entities ( $row_data[8] );
    print "<td><a href=\"" . $row_data[10] . "\">Link</a>";
}

print "</table>\n";

print "</body></html>\n";

и в данный момент оно выводит абсолютно все репорты о багах, которых собралось уже около 20000 и все это фомируется на одной странице, что не очень удобно...
Прошу у вас помощи.  
Вижу два решения проблемы: либо выводить на жэкран  - последних 200 репортов, либо добавить страницы (на каждой из которой будет 200 репортов)
Так как с  Perl, не работал вообще, то  синтаксис его для меня не понятен (частично).
Для реализации 1-го варианта понимаю что необходимо поправить цикл While... но условие выхода из него для меня сложно реализовать.
Для реализации 2-го идей вообще нет, т.к. не знаю способов добавление страниц...
Заранее спасибо.


Автор: arto 27.3.2009, 15:28
sql понимает limi и offset

Автор: kall1sto 27.3.2009, 15:41
Цитата(arto @  27.3.2009,  15:28 Найти цитируемый пост)
sql понимает limi и offset


сорь, как писал уже синтаксис не знаю... 
понимаю что нужноменять эту строку:


Код

while ( @row_data = $sth->fetchrow_array () )

но условия выхода не понимаю...
и можно ли написать путем??? (это просто алгоритм...)
a=1
b=20000
while (a=(b-200)) 
{
выводим сообщения:
a=a+1
}
интересует можно ли фиксировано в условии выхода из цикла вставить цифру 200

Автор: NuINu 27.3.2009, 15:57
задачи:
1.выучить перл
2.выучить sql

Автор: kall1sto 27.3.2009, 16:06
Цитата(NuINu @  27.3.2009,  15:57 Найти цитируемый пост)
задачи:
1.выучить перл
2.выучить sql


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

Код

while ( @row_data = $sth->fetchrow_array () )


но по-моему форум и существет для беседы и  помощи.

Автор: ginnie 27.3.2009, 16:27
kall1sto, 

Код

my $sth = $dbh->prepare ( 'SELECT * FROM `reports` ORDER BY `id` DESC LIMIT 200;' );


вариант со страничным разбиением будет сложнее.

Автор: tolkien 27.3.2009, 16:29
Тебе выше уже написали подсказку. SQL LIM и OFFSET.
В гугле набери эти слова получаешь массу примеров как это писать и что это делает

Автор: kall1sto 27.3.2009, 17:32
Пасиб отозвавшимся...
релизовал через страницы: (нужен дополнительный файл) итого получилось так:
первый файл:
Код

#!/usr/bin/perl

use DBI;
use HTML::Entities;
my $dbh = DBI->connect ( 'dbi:SQLite:dbname=..\bugserver.db' );
my $sth = $dbh->prepare ( 'SELECT * FROM reports ORDER BY id;' );
my $row_count = $dbh->prepare('SELECT COUNT(id) FROM reports;');
$row_count->execute ();
$sth->execute ();

print "Content-Type: text/html\n\n";
print "<html><body>\n";
print "<h1>Recent reports</h1>\n";

print "<table border=1>\n";

print "<tr><th>ID<th>Date<th>Version<th>Machine<th>Exception<th>Module<th>Function<th>Report file\n";

my @row_data;
my $count;

while ( @row_data = $sth->fetchrow_array () )
{
    if ($row_data[0] >= 0 && $row_data[0] <= 200)
    {
        print "<tr>";
        print "<td>" . $row_data[0];
        print "<td>" . $row_data[1];
        print "<td>" . $row_data[2];
        print "<td>" . $row_data[3];
        print "<td>" . $row_data[5];
        print "<td>" . $row_data[6];
        print "<td>" . encode_entities ( $row_data[8] );
        print "<td><a href=\"" . $row_data[10] . "\">Link</a>";
    }
}
print "</table>\n";

print "<br>";
my $hlp = int($row_count->fetchrow_array ()/200);
my $i = 0;

while ($i < $hlp+1)
{
    print " <a href=\"report_list_hlp.pl?n_page=$i\">$i</a> ";
    $i = $i+1;
}
print "<br>";

print "</body></html>\n";


второй файл:
Код

#!/usr/bin/perl

use DBI;
use CGI qw(:standard);
use HTML::Entities;
my $dbh = DBI->connect ( 'dbi:SQLite:dbname=..\bugserver.db' );
my $sth = $dbh->prepare ( 'SELECT * FROM `reports` ORDER BY `id`;' );
my $row_count = $dbh->prepare('SELECT COUNT(id) FROM reports;');
$row_count->execute ();
$sth->execute ();

print "Content-Type: text/html\n\n";
print "<html><body>\n";
print "<h1>Recent reports</h1>\n";

print "<table border=1>\n";

print "<tr><th>ID<th>Date<th>Version<th>Machine<th>Exception<th>Module<th>Function<th>Report file\n";

my @row_data;

my $pagek = param("n_page");
my $count;

while ( @row_data = $sth->fetchrow_array () )
{
        if ($row_data[0] >= $pagek*200 && $row_data[0] <= $pagek*200+200)
    {
        print "<tr>";
        print "<td>" . $row_data[0];
        print "<td>" . $row_data[1];
        print "<td>" . $row_data[2];
        print "<td>" . $row_data[3];
        print "<td>" . $row_data[5];
        print "<td>" . $row_data[6];
        print "<td>" . encode_entities ( $row_data[8] );
        print "<td><a href=\"" . $row_data[10] . "\">Link</a>";
    }
}
print "</table>\n";

print "<br>";
my $hlp = int($row_count->fetchrow_array ()/200);
my $i = 0;

print "<br>";
while ($i < $hlp+1)
{
    print " <a href=\"report_list_hlp.pl?n_page=$i\">$i</a> ";
    $i = $i+1;
}
print "<br>";


print "</body></html>\n";



Добавлено через 3 минуты и 28 секунд
ginnie, 
отдельное спасибо )
вставил еще и твой скрипт )

Автор: ginnie 27.3.2009, 20:52
kall1sto, делать ограничения в цикле выборки данных 

Код

while ( @row_data = $sth->fetchrow_array () )


без ограничения количества получаемых данных (20000 строк) -  плохая идея!

Автор: mastercz 28.3.2009, 11:17
ИМХО,  плохо решена задача. Тут, сразу же посоветовали вам использовать limit и offset
Смысл не в том чтобы, перебирать каждый раз все 20000 записей, что занимает время. А скармливать
скрипту очередную порцию записей из из базы данных.
(limit =200, а offset (Npage-1)*limit).
Ваш скрипт очень быстро переделываеться под это. Вы удивитесь, насколько быстрее будет отображаться ваша, 99-ая страница.




Автор: myth777 30.3.2009, 17:33
Делается с помощью LIMIT - стандартная ф-ция мускула + создание линков для перехода по PAGE страницы.

Автор: ginnie 30.3.2009, 17:40
Цитата(myth777 @  30.3.2009,  17:33 Найти цитируемый пост)
Делается с помощью LIMIT - стандартная ф-ция мускула

небольшое замечание: в самом первом сообщении указано, что данные берутся из SQLite  smile (там LIMIT тоже есть)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)