我在Perl中运行DBI并且无法弄清楚当我运行预准备语句时,我可以判断返回的行数是否为0。
我意识到我可以在我的while循环中设置一个计数器来获取我的行,但我希望有一种不那么难看的方法。
答案 0 :(得分:19)
答案 1 :(得分:11)
"caveat" in the documentation(与另一个答案的评论相关联)很重要,并提供真实,正确的答案:
通常,在非 -SELECT执行后(对于某些特定操作,如UPDATE和DELETE),或者在获取SELECT语句的所有行之后,您只能依赖行计数。
对于SELECT语句,通常无法知道将返回多少行,除非通过全部获取它们。某些驱动程序将返回应用程序到目前为止所获取的行数,但其他驱动程序可能会返回-1,直到获取所有行为止。因此,不建议使用rows方法或带有SELECT语句的$ DBI :: rows。
答案 2 :(得分:9)
为了找出结果集中有多少行,您有两个选项:
select count(*)
你可以通过存储过程引入一些魔法,它返回一个数组或更奇特的东西,但最终需要发生这两件事之一。
所以,没有花哨的方式来获得这个结果。你只需要计算它们: - )
答案 3 :(得分:4)
有点晚了,但是如果有人使用ORACLE,那么这就是汗水解决方案:
SELECT
q.*,
ROWNUM DB_ROWNUM,
(SELECT max(ROWNUM) FROM ($sql)) DB_COUNT
FROM
($sql) q
当然,$ sql是你的查询。 Oracles优化器非常智能,不会执行所有操作。
现在,每个获取的行都包含DB_ROWNUM中的当前行号(对于分页网格行编号很有用)以及DB_COUNT中的完整行数。你仍然需要获取至少一行(因此它不完全是上述问题的答案;)),但接下来会出汗:
这也是在Oracle中启动和限制的一种非常简单的方法,并且仍然可以获得完整的行数:
SELECT * FROM (
SELECT /*+ FIRST_ROWS($limit) */
q.*,
ROWNUM DB_ROWNUM,
(SELECT max(ROWNUM) FROM ($sql)) DB_COUNT
FROM
($sql) q
WHERE
ROWNUM <= $limit
)
WHERE
DB_ROWNUM > $start
这样,您实际上只能为网格中的第二页获取第51行到第100行,但仍然具有实际行号(从1开始)和每个获取行中的完整计数(没有开始和限制)。
答案 4 :(得分:2)
尝试此SQL解决方案,将数据的SQL与计数语句结合使用。
select null, null, null, count(*) from tablex union select foo, bar, foobar, null from tablex
第一个语句将具有计数,并且应该是第一行(如果不是,您可以通过它来绕过它),那么您可以在闲暇时循环记录其余部分。
答案 5 :(得分:2)
CPAN说:
[...]或在获取SELECT语句的所有行之后。
所以做这样的事情可能会奏效:
$sth->execute() or die $sth->errstr();
my $hasref = $sth->fetchall_hashref('id');
say "There is/are " . scalar(keys(%{$hasref}) . " row(s).";
答案 6 :(得分:1)
我已动态生成SQL并执行它。对我来说select count(*)
似乎不是一个选项,因为我必须再次重新生成查询。以下方法看起来很干净。但您必须再次发出s $h->execute()
以检索行数据。
$h->execute() or die "ERROR: Couldn't execute SQL statement";
$rowcount_ref = $h->fetchall_arrayref(0);
$rowcount = scalar (@{$rowcount_ref});
- Shaakunthala
答案 7 :(得分:0)
行肯定会因看起来的数据库/驱动程序版本而异。我肯定会在那里找到一个处理意外结果的逻辑。
答案 8 :(得分:0)
如果您想知道在遍历所有行之前有多少行,则特定于MySQL的解决方案可以是FOUND_ROWS()。
在第一次查询中,在SQL_CALC_FOUND_ROWS
之后立即添加SELECT
。然后执行SELECT FOUND_ROWS();
,您就可以立即访问行数了。现在,您可以决定是要遍历所有行,还是最好的方法。
请注意,在查询中使用LIMIT
将为您提供在没有LIMIT
的情况下返回的查询总数。
答案 9 :(得分:0)
正如其他人已经说过的那样,你真的需要获取行来查明是否存在。如果在每行开始循环之前需要知道,并且预期结果不是很大,那么可以将所有结果都放到一个数组中,然后检查它。
我最近使用过这样的东西:
foreach my $table ( qw(ACTOR DIRECTOR PRODUCER WRITER) ) {
my $sth = $dbi->prepare(qq{SELECT * FROM $table WHERE DESCRIPTION != TRIM(DESCRIPTION)})
or die $dbi->errstr;
$sth->execute or die $sth->errstr;
my @rows = @{ $sth->fetchall_arrayref() };
next unless @rows;
foreach my $row (@rows) {
print join(", ", map {qq("$_")} @{$row}), "\n";
}
}
答案 10 :(得分:0)
我只是让数据库进行计数。如果您想要的只是行数。 找到2018年1月的所有行。
$year='2018';
my $qry = "SELECT COUNT(`my_key`) FROM `mtable` WHERE `my_date` LIKE '$year-01-%';";
my ($count) = $dbc->selectrow_array($qry);
答案 11 :(得分:0)
我认为使用引用可以很容易地实现这一点。 下面的代码展示了如何不需要重新执行查询以在计数后获取行。
my $sth = $dbh->prepare("SELECT NAME, LOCATION
FROM Employees");
$sth->execute() or die $DBI::errstr;
$nrows = $sth->fetchall_arrayref() ;
print "Number of rows found :" . @$nrows . "\n";
#while (my @row = $sth->fetchrow_array()) {
foreach my $row(@{$nrows}) {
my ($name, $location ) = @$row;
print " Name = $name, Location = $location\n";
}
我希望这能满足这里提出的问题。