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 を実行します。しかし、これは明らかに DB にとって余分な作業です。

  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 に答える