2013-05-03 1 views
2

Я работаю с perl DBI в первый раз на этой неделе.Почему perl DBI возвращает 0 строк, когда оператор возвращается из трассировки 1

Большинство запросов/вставок работают нормально, однако у меня возникают проблемы с одним конкретным запросом, который возвращает 0 строк. Когда я включаю трассировку для Perl DBI и копирую то же самое заявление из трассировки на сервер (через HeidiSQL), возвращается 1 строка.

Есть ли какая-то двусмысленность в исходном SQL-запросе? Цель состояла в том, чтобы извлечь строку с самой последней меткой времени. В столбце временной метки нет дубликатов.

Начальная настройка для подключения БД:

$dsn = 'dbi:mysql:<servername>:<port>'; 
$dbh = DBI->connect($dsn, "<username>","<password>") or die "unable to connect $DBI::errstr\n"; 

Подготовка и исполняющего заявление: кода достигает печать «нет строк найдены»

my $sth = $dbh->prepare("SELECT name, location, timestamp, notified FROM storage 
    WHERE name = ? AND location = ? 
    AND timestamp = (SELECT MAX(timestamp) FROM storage)"); 

$sth->execute($strg_data->{name}, $strg_data->{location}); 

my @latest = $sth->fetchrow_array(); 

if (@latest) { 
    <snipped> 
} 
else { 
    print "no rows found!\n"; 
} 

экстракта из Perl DBI трассы (установлен уровня 2):

-> prepare for DBD::mysql::db (DBI::db=HASH(0xebe4c0)~0xec0010 'SELECT name, location, timestamp, notified FROM storage 
WHERE name = ? AND location= ? AND timestamp = (SELECT MAX(timestamp) FROM storage)') 
Setting mysql_use_result to 0 
<- prepare= DBI::st=HASH(0xecd7d0) at monitor.pl line 147 
-> execute for DBD::mysql::st (DBI::st=HASH(0xecd7d0)~0xec9e50 'xxxx' '/tmp/') 
-> dbd_st_execute for 00ecd7a0 
    -> mysql_st_interal_execute 
    Binding parameters: SELECT name, location, timestamp, notified FROM storage 
WHERE name = 'xxxx' AND location= '/tmp/' AND timestamp = (SELECT MAX(timestamp) FROM storage) 
    <- mysql_st_internal_execute returning rows 0 
<- dbd_st_execute returning imp_sth->row_num 0 
<- execute= '0E0' at monitor.pl line 152 

ответ

2

SELECT MAX(timestamp) FROM storage находит e максимальная временная метка без учета имени и местоположения. Если имя и местоположение, которые вы указали, не имеют записи с этой меткой времени, вы получите 0 строк.

Вы, вероятно, хотите этот запрос вместо:

SELECT name, location, timestamp, notified FROM storage 
    WHERE name = ? AND location = ? 
    ORDER BY timestamp desc LIMIT 1 
+0

работает правильно теперь с модификацией для добавления ИНЕКЯ к вложенным SELECT MAX (метки времени). Мне непонятно, почему я получаю возвращенную строку от другого SQL-клиента - должны ли результаты от Perl DBI и HeidiSQL не совпадать в этом случае? – tom

+0

Да, версия ORDER BY подходит и может быть предпочтительнее вложенного запроса - ее легче читать наверняка. – tom

+0

@ user1792772, возможно, таблица изменилась между запросами. – cjm