Perl 确定$sth是否有行而不使用它?
使用Perl 确定$sth是否有行而不使用它?,perl,dbi,Perl,Dbi,使用DBI是否有方法确定SELECT语句的已执行语句句柄是否会返回任何行而不从中提取 例如: use DBI; ... my $sth = $dbh->prepare("SELECT ..."); $sth->execute; if (..$sth will return at least one row...) { ... } else { ... } 我想执行测试,$sth将返回至少一行,而不对$sth执行任何获取方法 注意-我不需要精确的行数(即,$sth->ro
DBI
是否有方法确定SELECT语句的已执行语句句柄是否会返回任何行而不从中提取
例如:
use DBI;
...
my $sth = $dbh->prepare("SELECT ...");
$sth->execute;
if (..$sth will return at least one row...) {
...
} else {
...
}
我想执行测试,$sth将返回至少一行,而不对$sth
执行任何获取方法
注意-我不需要精确的行数(即,$sth->rows
),我只需要知道$sth->rows
是否将>0。$sth->行仍然是您的最佳选择。正如你所说的,只要检查它是否大于0
if ($sth->rows > 0){
# magic here!
}
除了!DBI文档说,在获取所有行之前,这对于select语句是不可靠的。没有办法确定将提前提取多少行。如果你需要知道这一点,建议你首先做一个
select count(*) from <table>
从中选择计数(*)
请参阅。您可以使用SQL,而不是在DBI中查找某些内容。只需将SELECT包装到另一个具有EXISTS条件的SELECT中:
SELECT 1 FROM DUAL WHERE EXISTS ( SELECT ... );
它不是可移植的SQL:FROM DUAL在RDBMS上可能看起来不同,DB可能不支持EXISTS和子查询。然而,大多数现代的DBs允许你做这样的东西
这应该是最有效的方法,因为优化器可以跳过对子查询的“忽略顺序依据”、“分组依据”限制。检查执行计划
SELECT COUNT(*) FROM ( SELECT ... )
也可以,但DB必须检查整个数据集,以获得正确的行数
如果您控制SQL builder,那么您可以删除order by、group by(只有在没有having part的情况下)并在其上应用限制以仅选择一行。也许这就是您要查找的
“活动”(布尔值,只读)
如果句柄对象为“活动”,则“活动”属性为真。这在应用程序中很少使用。目前,active的确切含义有些模糊。对于一个数据库,它通常会被处理
表示句柄连接到数据库(“$dbh->disconnect”设置为“Active”关闭)。对于语句句柄,它通常意味着句柄是一个“SELECT”,可能需要获取更多数据。
(获取所有数据或调用“$sth->finish”将关闭“Active”。我认为除了获取行之外,没有任何可靠的方法来测试是否可以获取任何行。当然,一旦您获取了第一行,就无法获取它,您必须将其“拿在手里”。但这并不难处理
我通常认为使用以下两种习惯用语之一:
...
$sth->execute;
my @rows;
my $row = $sth->fetchrow_hashref();
if ($row) {
do {
# do something with $row
...
$row = $sth->fetchrow_hashref();
} while ($row);
} else {
# No rows
}
或
不可以。正如您在回答中所引用的,Active
通常意味着语句句柄可能有更多行要获取。因此,即使是我们事先知道不会返回任何行的已执行语句(在典型的驱动程序下,如DBD::mysql
)也会报告Active
,直到调用第一个(也是最后一个)fetch(),$sth->rows只返回受更新、删除和插入影响的行数,而对于selects()则返回-1,如果预期结果的大小合理,则直接使用$sth->fetchall\u arrayref()
。
...
$sth->execute;
my @rows;
while (my $row = $sth->fetchrow_hashref()) { push @rows, $row }
if (@rows) {
# Some rows, now in @rows
} else {
# No rows
}