为什么 Perl DBI 返回 0 行,而跟踪语句返回 1 行?

3
我这周第一次使用perl DBI进行工作。
大多数查询和插入操作都能正常运行,但是我在一个特定的查询上遇到了返回0行的问题。当我启用perl DBI的跟踪功能,并从跟踪中复制完全相同的语句到服务器(通过HeidiSQL),会返回1行。
原始SQL查询中是否存在歧义?目的是检索具有最近时间戳的行。时间戳列中不存在重复项。
DB连接的初始设置为:
$dsn = 'dbi:mysql:<servername>:<port>';
$dbh = DBI->connect($dsn, "<username>","<password>") or die "unable to connect    $DBI::errstr\n";

准备并执行语句: 代码到达print 'no rows found'

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个回答

3

SELECT MAX(timestamp) FROM storage WHERE name='your_name' AND location='your_location' 找到指定名称和位置的最大时间戳。如果您指定的名称和位置没有该时间戳的记录,则将返回0行。

您可能需要使用以下查询:

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

现在已经可以正常工作了,修改后添加了WHERE子句到嵌套的SELECT MAX(timestamp)中。我不清楚为什么会从不同的SQL客户端返回一行结果 - 在这种情况下,Perl DBI和HeidiSQL的结果不应该匹配吗? - tom
是的,ORDER BY 版本是合适的,而且可能比嵌套查询更好 -- 它肯定更容易阅读。 - tom
1
@user1792772,可能是查询之间表格发生了变化。 - cjm
是的,我刚刚意识到脚本的下一步是插入到同一张表中,这意味着在运行我的手动查询时,数据已经发生了变化,并且有一行新的时间戳和匹配的姓名+位置。谢谢你的帮助。 - tom
看起来你应该使用 $dbh->last_insert_id - ikegami

1
我知道这是一个旧的帖子,但我遇到了相同/类似的情况——我的Perl DBI通过MySQL查询返回0条记录,而在命令行上执行相同的查询返回了多个结果。谷歌搜索让我找到了这篇2003年的问答:https://www.perlmonks.org/?node_id=312625,解决了我的问题——在获取调用时使用“defined”。
while (defined(my $data = $sth->fetchrow_array)) {}

为什么使用Perl DBI在同一张表上进行相同的查询,有些列可以返回数据,而有些列却返回空值(如上所述),这仍然是一个谜。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接