• ベストアンサー
  • すぐに回答を!

fetchrow_arrayとfetchrow_hashrefの使い方

  • 質問No.409852
  • 閲覧数5566
  • ありがとう数4
  • 気になる数0
  • 回答数2
  • コメント数0

お礼率 82% (58/70)

Jやまとです。
PerlからSELECT文を実行して結果の行の値を取得する単純なスクリプトを作成しています。
(1)fetchrow_array使用
(2)fetchrow_hashref使用
以上2通りの方法で試したのですが、(2)がInternal Server Errorになります。
原因が全く分かりません。
分かる方いらしゃいましたら、ご教授願います。
OS:TurboLinux6.2
DB:Oracle8i
Apache,PerlはTurboLinux6.2に入っているものをそのまま使用
以下、ソースを記載します。
---------------
(1)fetchrow_arrayを使用して行の値を取得(こっちは動く)
$dbh = DBI->connect($ds, $user, $pass) || &dbErr("Database can't connect." . $DBI::errstr);
$sql = "SELECT SYSDATE FROM DUAL \n";
$sth = $dbh->prepare( $sql );
$sth->execute or die "Cannot execute. " . $sth->errstr();
$cnt1 =1;
while (@row = $sth->fetchrow_array()) {
@{$get_date[$cnt1]} = @row;
$cnt1++;
}
---------------
(2)fetchrow_hashrefを使用して行の値を取得(こっちが動かない)
$dbh = DBI->connect($ds, $user, $pass) || &dbErr("Database can't connect." . $DBI::errstr);
$query = qq{
SELECT SYSDATE FROM DUAL
};
$sth = dbh->prepare($query);
$sth->execute(); # 実行
if($sth->rows() != 1){ # 該当する行数
# エラー処理
}
$rhash = $sth->fetchrow_hashref();
%hash = {%{$rhash}};
$sth->finish();
$get_date = $hash{SYSDATE};
---------------
(2)実行時のerror_log
Can't locate object method "prepare" via package "dbh" at /u01/ora1/www/htdocs/hoge.cgi line 30.
Premature end of script headers: /u01/ora1/www/htdocs/hoge.cgi
---------------
(本文長くてすみません)

質問者が選んだベストアンサー

  • 回答No.2
  • ベストアンサー

ベストアンサー率 75% (30/40)

rowsメソッドと同じく、executeが正しく処理レコード数を返すのは、非select文を実行した場合のみです。
select文の場合、rowsもexecuteも0行と認識するDBDが多いです。
で、これはselect文に限らずですが、処理レコード数が0の場合は、0自体ではなく「0E0」を返します。
これは、0を返すと、実行エラー時の戻り値undefと同様、
if ($sth->execute) {} で失敗したのと同じことになってしまうためです。
select文の行数は、fetchしながら行数をカウントするか、取り込んだ、配列、ハッシュの数をカウントするのが一般的な方法ですね。fetchする前に取得する方法はわかりません。
お礼コメント
jyamato

お礼率 82% (58/70)

なるほど・・・こう言う事だったのですね。
とても分かり易い説明でした。

fetchしながらカウントするしかないようですね。
ありがとうございました。
投稿日時:2002/11/21 19:14

その他の回答 (全1件)

  • 回答No.1

ベストアンサー率 75% (30/40)

いくつも気になる点がありますが...
間違いは、
$sth = dbh->prepare($query);
のdbhは$dbhと書きましょう。

あとは参考までに。

if($sth->rows() != 1) {}
そもそもrowsメソッドはselect分のクエリでは使わないことが強く推奨されています。
ただしい行数を返すDBDはほとんどありません。
エラーチェックは、execute実行時と、$DBI::errで確認するのが基本です。

次に、sql文の最後には;を入れた方がいいでしょう。
$query = qq{ SELECT SYSDATE FROM DUAL; }; のように。
一応、DBIでは実行するようですが、SQL文としては不正確です。

%hash = {%{$rhash}};
ハッシュに入れなおすなら、hashrefを使う意味が無いのでは?
リファレンスのままデータにアクセスするからこそ、スピード的にも、メモリリソース的にも優れたプログラムになるのです。
$rhash->{SYSDATE}と書けばアクセスできます。

この程度の処理であれば、アトミックに
selectall_hashrefメソッドが可読性もよくなり、楽ですよ。prepare、execute、finishと手順を踏む必要が無いので。
補足コメント
jyamato

お礼率 82% (58/70)

できました。有難うございました。(お恥ずかしい・・・)
で、もう一つお聞きしたいのですが、executeした後、fetchをする前に、
取得したデータ件数を取りたいのですが。
調べた所、$rv = $sth->execute(); と書くと、$rvに処理した件数が格納
されると書いてありました。実際に試した所、$rvには「0E0」と訳分からない
値が返って来ました。(実際は46件のデータが返ってくるSQLを実行しました)

書き方がおかしいのでしょうか?
度々すみませんが、ご教授願えませんでしょうか?
宜しくお願い致します。
投稿日時:2002/11/21 16:00
結果を報告する
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,600万件のQ&Aを分析して最適な回答をご提案します。

関連するQ&A

その他の関連するQ&Aをキーワードで探す

ピックアップ

ページ先頭へ