dポイントプレゼントキャンペーン実施中!

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
---------------
(本文長くてすみません)

A 回答 (2件)

rowsメソッドと同じく、executeが正しく処理レコード数を返すのは、非select文を実行した場合のみです。


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

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

fetchしながらカウントするしかないようですね。
ありがとうございました。

お礼日時:2002/11/21 19:14

いくつも気になる点がありますが...


間違いは、
$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と手順を踏む必要が無いので。

この回答への補足

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

書き方がおかしいのでしょうか?
度々すみませんが、ご教授願えませんでしょうか?
宜しくお願い致します。

補足日時:2002/11/21 16:00
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!