• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:fetchrow_arrayとfetchrow_hashrefの使い方)

PerlでOracleデータベースから値を取得する方法

このQ&Aのポイント
  • Perlのfetchrow_arrayを使用してOracleデータベースから値を取得する方法について説明します。
  • fetchrow_hashrefを使用した値の取得方法に問題があり、Internal Server Errorが発生しています。
  • 原因を特定するために、プログラムのソースコードと実行時のエラーメッセージを提供しています。

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

  • ベストアンサー
  • retr
  • ベストアンサー率75% (30/40)
回答No.2

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

jyamato
質問者

お礼

なるほど・・・こう言う事だったのですね。 とても分かり易い説明でした。 fetchしながらカウントするしかないようですね。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • retr
  • ベストアンサー率75% (30/40)
回答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と手順を踏む必要が無いので。

jyamato
質問者

補足

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

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Mysqlの接続について

    現在、以下のようなperlのスクリプトを作っているのですが、mysqlへの接続,切断は以下の場合、どちらにした方がいいのでしょうか? (1)の場合 use DBI; $dsn="DBI:mysql:database=dbname:host=localhost"; $dbh=DBI->connect($dsn,'user','pass'); $sth = $dbh->prepare("SELECT no,title,name,date,host From `table1` where no='1'"); $sth->execute; $sth->fetchrow_array; $sth->finish; $sth2 = $dbh->prepare("SELECT no,title,name,date,host From `table2` where no='1'"); $sth2->execute; $sth2->fetchrow_array; $sth2->finish; $dbh->disconnect; (2)の場合 use DBI; $dsn="DBI:mysql:database=dbname:host=localhost"; $dbh=DBI->connect($dsn,'user','pass'); $sth = $dbh->prepare("SELECT no,title,name,date,host From `table1` where no='1'"); $sth->execute; $sth->fetchrow_array; $sth->finish; $dbh->disconnect; $dsn="DBI:mysql:database=dbname:host=localhost"; $dbh=DBI->connect($dsn,'user','pass'); $sth2 = $dbh->prepare("SELECT no,title,name,date,host From `table2` where no='1'"); $sth2->execute; $sth2->fetchrow_array; $sth2->finish; $dbh->disconnect; (1)の場合と(2)の場合の違いは、(1)の場合、最初にデータベースに接続して、一番最後に切断する事で、(2)の場合、毎回データベースへの接続と切断を行う事が違います。 (2)の場合、毎回接続と切断を行うので、2回ほどではあまり変わらないかもしれないのですが、もし10回とか接続と切断を行うとかなり負荷が高くなるような気がするのですが、他のHPなどを拝見すると接続をしたら切断を行うように癖をつけるようにした方がいいと書かれていたりします。 どちらの方が正しいやり方というか、負荷がすくなく使えるのでしょうか?

    • ベストアンサー
    • Perl
  • MySQLとの接続でfetchrow_arrayがwhile文で使えない

    こんばんは、皆さん。 MySQLをPerlから使いたいのですが、 以下のようにやっても、$flagに"OK"が入りませんでした。 つまり、whileは一度もループしないで抜けてしまっているようです。 ------------------------------------------------- use DBI; … sub dbtest{ $dbh = DBI->connect("dbi:mysql:hogeDB:localhost","user","pass"); $sql = "select hoge,fuge from t_name where key='value'"; $sth = $dbh->prepare($sql); $sth->execute; while( ($hoge, $fuge) = $sth->fetchrow_array ){     $flag = "OK"; } $sth->finish; $dbh->disconnect; } ------------------------------------------------- ※実際はユーザ名などは変数にしています。 バージョンは現在、 Perl:v5.8.5 MySQL:5.1.6-alpha となっているようです。 それとちょっと別件ですが、 use autouseの書式は以下でよいのでしょうか? 「use autouse DBI;」 しかし、これだけだとDBIが読み込めてないエラーになるようです。 ご教示よろしくお願いします。

    • ベストアンサー
    • Perl
  • ハッシュのキー追加について

    とある既存プログラムに機能追加したいのですが上手くいきません。 ハッシュだとは思うのですが、%だったり$だったりしてよくわからなくなってしまいました。 どこがおかしいか教えていただけないでしょうか。 <概要> もともとあった(1)と(3)の処理の間に、(2)を行う <ソース> (1)DBから1レコードを取得する $sql = "select * from tenpo where id=5;"; $sth = $dbh->prepare($sql); $sth->execute(); $shop = $sth->fetchrow_hashref(); (2)別TABLEから値を取得し、(1)に追加する $sql = "select todoufuken from area where id=5;"; $sth = $dbh->prepare($sql); $sth->execute(); @todoufuken= $sth->fetchrow_array; $shop{place} = $todoufuken[0]; (3)$shopの情報をサブルーチンに渡す ソース略

    • ベストアンサー
    • Perl
  • perlでdb(mysql)に接続

    perlでdb(mysql)に接続し、取得したデータを 表示させるというようなことをしたいのですが、うまく いきません。 ファイル名test.cgi mysqlのバージョンは 5.0.45で 記述は以下です。 #!/usr/bin/perl use DBI; my $dbh = DBI->connect("DBI:mysql:database, "userid", "password"); my $sth = $dbh->prepare('SELECT * FROM tablename'); $sth->execute; print "Content-Type: text/plain\n\n"; print "\n"; while(my @row = $sth->fetchrow_array) { print "$row[0]:$row[1]\n"; } $sth->finish(); $dbh->disconnect(); exit; ブラウザで確認すると何も表示されず、ログとして 以下のエラーが確認できます。 DBD::mysql::st execute failed: Table 'database.tablename' doesn't exist at test.cgi line 8. DBD::mysql::st fetchrow_array failed: fetch() without execute() at test.cgi line 11. my $sth = $dbh->prepare('SELECT * FROM tablename'); で指定したテーブルは存在しておりますし、SQL文の記述も 問題ないと思われます。 また、ファイルのパーミッションは705(755でも同様の結果)です。 perl初心者のため、どこが問題なのか検討がつきません。 ご助言いただきたく存じます。 よろしくお願いいたします!

    • ベストアンサー
    • Perl
  • SQLで別テーブルの参照

    こんにちは。 PostgreSQL+Perl+DBIでCGIを書いています。 テーブルからデータを取得する場合なのですが、table1にはIDのみが登録されていて、table2には、そのIDに対する文字列が登録されているとします。 このような場合に、tableからIDを取得して、そのIDに対するtable2の文字列を一気に取得することは可能でしょうか? つまり、 $dbh=DBI->connect(~); $sth=$dbi->prerare("SELECT id FROM table1 WHERE ~;"); $sth->excecute(); $id=$sth->fetchrow; $sth->finish(); $sth=$dbi->prerare("SELECT str FROM table2 WHERE id=$id;"); $sth->excecute(); $str=$sth->fetchrow; $sth->finish(); $dbh->disconnect(); といった処理をこんな感じに一度に行いたいのです。 $dbh=DBI->connect(~); $sth=$dbi->prerare("~~~~~;"); $sth->excecute(); $str=$sth->fetchrow; $sth->finish(); $dbh->disconnect(); 可能かどうかもわからないのですが、なにか良い方法はありますでしょうか?よろしくお願いします。

  • 最大値の数をカウントしたい

    初心者ですが、よろしくお願いします。 Pointの最大値を持つレコードの件数をカウントするために、 $sth = $dbh->prepare(SELECT COUNT(MAX(Point)) FROM table); $sth -> execute(); $count = $sth -> fetchrow_array(); としたのですが、うまくいきません。 COUNT()の中にMAX()を入れられないのでしょうか? だとしたらどのように書けば動くようになるでしょうか? 初歩的な質問かもしれませんが、いろいろ調べてもよくわかりません。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 一回の処理で、2回以上データベースに対してアクセスできない??(perlDBIを使用)

    質問があるのですが、よろしくお願いします。 use DBI; $dbuser = 'root'; $passwd = 'abc'; $db = DBI->connect('DBI:mysql:DB:localhost',$dbuser, $passwd); $prepare = "select MAIL from user where USER_ID = $userid"; $sth->prepare("$prepare"); $sth->execute; @user = $sth->fetchrow_array; $sth->finish; while( ($key, $value) = each %in ){ $sth = $db->prepare("UPDATE user SET $key = '$value' where USER_ID = $in{userid}"); $sth->execute; $sth->finish; } $db->disconnect; という処理を行わせたいのですが、どうもUPDATE文の辺りで、処理が止まってしまっているようなのです。select文はしっかり実行されている形跡があるのですが、1回の処理で2回以上データベースに対してアクセスすることは出来ないのでしょうか? どなたか分かる方いらっしゃいましたらご教授のほどよろしくお願いします。

    • ベストアンサー
    • MySQL
  • perl >> DBI >> DBD >> oracle8でエラー

    perlからDBI経由でoracleに接続したいのですが、 なぜか DBI->connectのところで失敗して下記のようなエラーが出ます。 `CONNECT ERROR ORA-1034: ORACLE not available oas userでtelnetで入り、直接perl scriptを起動すると問題なく動作するの ですが、なぜかOAS経由でブラウザーからCGIとしてcallすると 失敗するのです。 もう2日も悩んでます。 どなたか原因がわかりましたらご教授ください。 ---- 環境 --- perl 5.005_03 OAS 4.0.8.1 DBI 1.30 DBD-Oracle 1.12 OS solaris2.6 接続先DBは別のsolarisマシンに入ってる。 ----------------ソース----------------------------- #!/usr/local/bin/perl use DBI; $dsn = 'DBI:Oracle:orcl'; $user = 'testuser'; $password = 'testuserpass'; $dbh = DBI->connect($dsn, $user, $password) or die "接続できません"; my $sth = $dbh->prepare("select * from munec"); $sth->execute; while(@row = $sth->fetchrow_array) { print "@row\n"; } ---------------

  • ステートメントハンドルのクローズに失敗?

    お世話になります。 早速ですが、WindowsXP+perl5.8.8+sqlite3の環境で以下のようなプログラムを作成しました。 #!/usr/bin/perl use DBI; $mydb = "mokdb"; $hDB = DBI->connect( "dbi:SQLite:dbname=$mydb","","",{PrintError=>0} ); $sql = "select * from tshoku"; $sth = $hDB->prepare($sql); my $rv = $sth->execute; while( my $rs = $sth->fetchrow_hashref ){ print $rs->{'ts_key'},"\n"; } $sth->finish; $hDB->disconnect; exit; これを実行すると、テーブル"tshoku"内の項目"ts_key"がずらっと表示されるのですが、その後、$hDB->disconnect;のタイミングで "closing dbh with active statement handles" という警告が表示されます。 $hDB->disconnect;の直前にステートメントハンドルはクローズしているにもかかわらずこのような警告が表示されてしまうのは何故でしょうか?

    • ベストアンサー
    • Perl
  • SQLが応答しなくなっているのか、CGIが読み込み中のままになってしまいます。

    SQLを約1600回実行したら、5秒後にページを再読み込みします。 print "<html><body onload=\"setTimeout('location.reload()',5000)\">"; foreach ... {   ...   # 約1600回繰り返す   @result = select("SQL文");   ... } sub select{   my @result = ();   my($dbh, $sth);   $dbh = DBI->connect('DBI:mysql:データベース:localhost', "ID", "パスワード") or return 0;   $sth = $dbh->prepare("$_[0]");   $sth -> execute() or return 0;   $num_rows = $sth->rows;   $num_of_fields = $sth->{NUM_OF_FIELDS};   $result[0] = $sth->rows;   for ($i=1; $i<=$num_rows; $i++) {     @fetchrow_array = $sth->fetchrow_array;     $result[$i] = join ',', @fetchrow_array   }   $sth -> finish();   $dbh -> disconnect();   return @result; } 最初の1,2回は期待通りに動くのですが、 2,3回ほど再読み込みをすると、「読み込み中」のままになってしまいます。 (期待通りに動く場合、1回の読み込みは20秒程度です。) タスクマネージャを見ると、 期待通りに動いているときは、CPU使用率が60%くらいになっていますが、 「読み込み中」のままの時は1%程度になっています。 SQLサーバーから応答がなくなっているのでしょうか? (簡単なSQLにしてみても同じでした。) 原因がわかる方、よろしくお願いします。 WindowsXP SP2 Apache1.3 ActivePerl5.6 MySQL3.23

    • ベストアンサー
    • CGI
TWS10でPCと接続に関して
このQ&Aのポイント
  • PANASONIC Let’s Note を使用している際に、TWS10ヘッドセットで音声が聞こえず、声も繋がらないという問題が発生しています。
  • ステレオでは音声が聞こえるが、TWS10ヘッドセットを使用すると音声が聞こえないという問題があります。
  • エレコム株式会社の製品であるTWS10ヘッドセットを使用している際に、PANASONIC Let’s Note で音声が聞こえないという問題が発生しています。
回答を見る

専門家に質問してみよう