URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7099
[ Назад ]

Исходное сообщение
"Как получить массив элементов из результата sql запроса"

Отправлено BaldyMan , 10-Янв-08 18:43 
Хочу написать свой редиректор для сквида.
В перле не силен, говорю сразу.
Вот ло чего уже дошел:
#!/usr/bin/perl
use DBI;
use DBI::DBD;
require "/etc/squid/logger.cfg";
$dbh = DBI->connect("DBI:mysql:$dbname:$dbhost:$dbport", $dbuser, $dbpass) or die "Cannot connect to DataBase";
$sth = $dbh->prepare("SELECT ip FROM auth;");
$|=1;
while (<>) {
  ($url, $cl_ip, $ident, $method) = /^(\S+) (\S+) (\S+) (\S+)$/;
$sth->execute;
@X = $sth->fetchrow_array();
foreach(@X)
  {

  }
$sth->finish;
#print "$url $who $ident $method\n" ;
}
$dbh->disconnect;

Запнулся на том месте, что fetchrow_arrow почему-то выдает мне только последнюю запись из выборки по табличке с ip клиентов. Может вместо этой функции использовать какую другую или вообще проверять не в самом скрипте ип клиента запросившего страницу, а через sql запрос чем-то типа "если есть в табличке в столбце с ипами ип клиента запросившего страницу, то переходить к проверке лимита" или всётаки лучше это делать в теле скрипта.

Заранее благодарен за ответ. И если можно, то пример напишите, как это можно сделать, т.к. в перле не силен пока ещё.


Содержание

Сообщения в этом обсуждении
"Как получить массив элементов из результата sql запроса"
Отправлено angra , 11-Янв-08 04:00 
"Смешались в кучу кони, люди" :)
fetchrow_array считывает одну _строку_(запись, record, row) и результатом будет массив состоящий из _столбцов_(полей, fields, columns). Используется либо в цикле, либо когда запрос должен вернуть заведомо одну строку, например когда есть условие с ключевым полем. Также отмечу что вместо /^(\S+) (\S+) (\S+) (\S+)$/ можно использовать просто split.

Если бы вы четко описали имеющиеся структуры данных и вашу задачу было бы легче помочь. Попробую немного телепатии:
Вы получаете со стандартного ввода и/или из файлов, переданных в командной строке, строки   в которых указан ip клиента и вам бы хотелось его сравнить с записью в базе данных.

В зависимости от размера таблицы auth, наличия свободной памяти и ограничений нагрузок на мускул возможны два варианта
1. За один раз считать всю таблицу auth в хеш с ключом по ip и в дальнейшем использовать этот хеш                                                          
2. На каждый ip делать отдельный запрос

В общем виде можно представить этот такой схемой
1.
$dbh = DBI->connect("DBI:mysql:$dbname:$dbhost:$dbport", $dbuser, $dbpass) or die "Cannot connect to DataBase";
my $ips=$dbh->selectall_hashref("SELECT ip FROM auth",1);                                                        
while (<>) {
  ($url, $cl_ip, $ident, $method) = split;
  if (exists $ips->{$cl_ip} {
    дальше необходимые действия если ip был найден                                                  
  }
}
2.  
$dbh = DBI->connect("DBI:mysql:$dbname:$dbhost:$dbport", $dbuser, $dbpass) or die "Cannot connect to DataBase";
$sth = $dbh->prepare("SELECT ip FROM auth where ip=?");                                                      
while (<>) {
  ($url, $cl_ip, $ident, $method) = split;                                          
  $sth->execute($cl_ip);
  if (($sth->fetchrow_array)[0]) {                                  
    дальше необходимые действия если ip был найден
  }  
}
Вообще говоря стоит подробней посмотреть perldoc DBI и поэкспериментировать с различными методами. Для наглядности стоит использовать Data::Dumper. Например так  
use Data::Dumper
while ($row=$sth->fetchrow_hashref(1)) {print Dumper($row);}