我正在尝试使用Perl在数据库中进行搜索,以判断是否存在具有特定ID的项目。此搜索不能返回任何行,但也可以返回一行。
我有以下代码:
my $th = $dbh->prepare(qq{SELECT bi_exim_id FROM bounce_info WHERE bi_exim_id = '$exid'});
$th->execute();
if ($th->fetch()->[0] != $exid) {
...
基本上,这会尝试查看是否返回了ID,如果不是,请继续执行脚本。但它在$th->fetch()->[0]
事件上抛出Null数组引用错误。
我怎样才能简单地检查它是否返回行或现在?
答案 0 :(得分:32)
DBD::mysql驱动程序有一个rows()
方法可以返回结果计数:
$sth = $dbh->prepare( ... );
$sth->execute;
$rows = $sth->rows;
这是特定于数据库驱动程序的,因此它可能在其他驱动程序中不起作用,或者在其他驱动程序中可能有所不同。
答案 1 :(得分:13)
my $th = $dbh->prepare(qq{SELECT bi_exim_id FROM bounce_info WHERE bi_exim_id = '$exid'});
$th->execute();
my $found = 0;
while ($th->fetch())
{
$found = 1;
}
如果该行不存在,您的查询将不会返回任何内容,因此您无法取消引用该提取。
更新:您可能希望将其重新编写为
my $found = $th->fetch();
答案 2 :(得分:4)
为什么不“选择计数(*)......”??
my ($got_id) = $dbh->selectrow_array("SELECT count(*) from FROM bounce_info WHERE bi_exim_id = '$exid'");
my $q_exid = $dbh->quote($exid);
my ($got_id) = $dbh->selectrow_array("SELECT count(*) from FROM bounce_info WHERE bi_exim_id = $q_exid");
或者如果你要执行这么多:
my $sth = $dbh->prepare("SELECT count(*) from FROM bounce_info WHERE bi_exim_id = ?");
....save $sth (or use prepare_cached()) and then later
my ($got_id) = $dbh->selectrow_array($sth, undef, $exid);
答案 3 :(得分:3)
更改选择以始终返回某些内容?这应该适用于Sybase,不管其他数据库是什么。
my $th = $dbh->prepare(qq{SELECT count(*) FROM bounce_info WHERE bi_exim_id = '$exid'});
$th->execute();
if ($th->fetch()->[0]) {
....
}
答案 4 :(得分:3)
总的来说,我不确定为什么人们如此害怕例外。你抓住它们继续前进。
my $sth = prepare ...
$sth->execute;
my $result = eval { $sth->fetchrow_arrayref->[1] };
if($result){ say "OH HAI. YOU HAVE A RESULT." }
else { say "0 row(s) returned." }
在这种情况下,保罗的答案是最好的。
此外,$sth->rows
通常不会起作用,直到您获取每一行。如果你想知道有多少行匹配,那么你必须向数据库引擎询问你想知道答案的问题;即select count(1) from foo where bar='baz'
。
答案 5 :(得分:1)
查找SELECT查询返回的行数的唯一可靠方法是获取所有行并计算它们。如the DBI documentation中所述:
通常,您只能依赖一行 非SELECT执行后计数(for 一些特定的操作,如UPDATE 和删除),或取得所有后 SELECT语句的行。
用于SELECT 声明,一般不是 可以知道将有多少行 返回除了通过全部获取它们。 一些司机将返回的号码 应用程序已获取的行 远,但其他人可能会返回-1直到 所有行都已获取。所以使用 rows方法或$ DBI :: rows with 建议不要使用SELECT语句。
但是,当你接下来的时候,无论如何你几乎不需要提前知道。只需循环while ($sth->fetch)
来处理每一行,或者对于只返回零行或一行的查询的特殊情况,
if ($sth->fetch) {
# do stuff for one row returned
} else {
# do stuff for no rows returned
}
答案 6 :(得分:1)
本文可能有助于MySQL用户:
http://www.arraystudio.com/as-workshop/mysql-get-total-number-of-rows-when-using-limit.html
幸运的是,自MySQL 4.0.0起,您可以在查询中使用SQL_CALC_FOUND_ROWS选项,这将告诉MySQL计算忽略LIMIT子句的总行数。您仍然需要执行第二个查询才能检索行数,但这是一个简单的查询,并不像检索数据的查询那么复杂。
用法非常简单。在主查询中,您需要在SELECT之后添加SQL_CALC_FOUND_ROWS选项,在第二个查询中,您需要使用FOUND_ROWS()函数来获取总行数。查询看起来像这样:
SELECT SQL_CALC_FOUND_ROWS name,email FROM users WHERE name LIKE'a%'LIMIT 10;
SELECT FOUND_ROWS();
唯一的限制是必须在第一个查询之后立即调用第二个查询,因为SQL_CALC_FOUND_ROWS不会在任何地方保存行数。
虽然此解决方案还需要两个查询,但速度要快得多,因为您只执行一次主查询。
您可以在MySQL文档中阅读有关SQL_CALC_FOUND_ROWS和FOUND_ROWS()的更多信息。