

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ベストアンサー
- 回答日時:
rowsメソッドと同じく、executeが正しく処理レコード数を返すのは、非select文を実行した場合のみです。
select文の場合、rowsもexecuteも0行と認識するDBDが多いです。
で、これはselect文に限らずですが、処理レコード数が0の場合は、0自体ではなく「0E0」を返します。
これは、0を返すと、実行エラー時の戻り値undefと同様、
if ($sth->execute) {} で失敗したのと同じことになってしまうためです。
select文の行数は、fetchしながら行数をカウントするか、取り込んだ、配列、ハッシュの数をカウントするのが一般的な方法ですね。fetchする前に取得する方法はわかりません。
なるほど・・・こう言う事だったのですね。
とても分かり易い説明でした。
fetchしながらカウントするしかないようですね。
ありがとうございました。
No.1
- 回答日時:
いくつも気になる点がありますが...
間違いは、
$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を実行しました)
書き方がおかしいのでしょうか?
度々すみませんが、ご教授願えませんでしょうか?
宜しくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlでdb(mysql)に接続
-
ACCESSのVBAでPrivate Sub ~en...
-
グラフのX,Y座標を取得したい
-
Excel VBA 定義されたプロージ...
-
モジュールからフォームのボタ...
-
acwzlibとは?
-
教えて下さい。
-
EXECEL VBA コマンドボタンか...
-
「デバイスは PRN を初期化でき...
-
PerlでUNIXのコマンドとパスワ...
-
モジュールアップデートって何...
-
[ASP]条件によってインクルード...
-
VBでグローバル変数を宣言するには
-
COBOL85からCOBOL2002移行
-
CPANモジュールのアンインストール
-
エクセルVBAでシートモジュール...
-
現在アクティブなフォーム名を...
-
Wordで、分かち書きをするVBA ...
-
VHDLにおける「generic」について
-
linux mintで(EE )Failed to lo...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Oracleのデータベースに接続で...
-
fetchrow_arrayとfetchrow_hash...
-
perlからmysqlに接続できない
-
perlのdbi-connect処理のエラー
-
テキストデータをpostgreSQLの...
-
PerlソースでのSQLのエラーにつ...
-
例外処理のフローチャートの記...
-
「デバイスは PRN を初期化でき...
-
Excel VBAでリンク切れをチェッ...
-
Excel VBA 定義されたプロージ...
-
Application.OnKey:項目入力中...
-
Excel VBAで、ユーザーフォーム...
-
モジュールの最大数はいくつな...
-
グラフのX,Y座標を取得したい
-
VBA This Workbookモジュール...
-
ユーザー定義関数に#NAME?が返...
-
LCD ディスプレイを Raspberry ...
-
VBSがコンパイルエラーになりま...
-
Excel VBAで、ユーザーフォー...
-
VBAで旧字体を異字体に一括で変...
おすすめ情報