2

我有一个使用 DBD::Oracle 对 Oracle 数据库执行 SELECT 的 perl 应用程序。

然后我想检查是否返回了任何行,并基于此进行分支。

DBD::Oracle 的 rows() 方法为 SELECT 返回 -1(根据 perldoc 和我的测试),所以我为 MySQL 所做的将行不通。

perldoc 提到 RowsInCache (“返回缓存中未提取的行数以进行选择”),但尝试从我的数据库或语句句柄调用或检查它不起作用。例如:

if ( $sth->RowsInCache > 0 )
if ( $sth::RowsInCache > 0 ) 
if ( $dbh->RowsInCache > 0 )
if ( $dbh::RowsInCache > 0 )

我得到“找不到对象方法”或“使用未初始化的值”。我的语法错误?

我知道有几种方法可以完成我想要的:

  1. 先做一个SELECT COUNT,看看行数,然后做真正的SELECT。但这显然是数据库的额外工作。

  2. 如果你打电话

    $row = $sth->fetchrow_hashref;

如果没有行,则 $row 将是未定义的,您可以对其进行测试。但是,如果你的意图是这样的......

$sth->execute($some_bind);
while ( $row = $sth->fetchrow_hashref ) {

...您必须包含一些愚蠢的逻辑来处理您已经获取第一行以测试是否有行的事实,或者执行以下操作:

$sth->execute($some_bind);
$got_some_rows = 0;
while ( $row = $sth->fetchrow_hashref ) {
    $got_some_rows = 1;
    # other stuff
}
$sth->finish;
if ( $got_some_rows == 0 ) {

...这不是世界末日,但是....如果看起来应该有一些简单的方法来说“嘿,数据库,你有我的行吗”?

我错过了一些明显的东西吗?

谢谢!

4

1 回答 1

4
$sth->RowsInCache;   # Wrong.  Method call for non-existent method.

$sth::RowsInCache;   # Wrong.  Looking for a variable $RowsInCache in package `sth'

$sth->{RowsInCache}  # Right.  RowsInCache is an attribute accessed as hashref element.

但是,考虑到您想要做的事情,这似乎更好:

...
$sth->execute;
while (my $row = $sth->fetchrow_hashref) {
  do_stuff_with($row);
}
if ($sth->rows == 0) {
  handle_the_case_where_there_were_no_results();
}
...

通常,DBI 驱动程序只能保证在所有行都被获取之后rows()是明智的,但这适用于你的情况。

于 2013-09-25T15:53:55.373 回答