• ベストアンサー

Perl<->Oracle間での文字化けについて

初投稿になります。過去ログを検索したのですが、似た質問はあるものの根本的な解決につながらなかったので、新規の投稿をさせていただきました。 乱文ご容赦ください。 今現在Oracleサーバ上でPerlのプログラムを組んでいます。とは言えPerlも既存の物を改変できる程度の知識ですし、DBに関しての知識はほぼ皆無です。 それでもNet等を参照しながら、どうにかDB内を参照できるようにはなってきました。が、ここで日本語の取り扱いについて突き当たってしまいました。 まずは以下のPerlファイルをご覧ください。 #ソースの前後は割愛 #DBに接続した後のソース # 読み込みcharセットの宣言 $dbh->do("set names 'ujis'"); # 動的SQL文の発行 $hSt = $dbh->prepare(" SELECT * FROM DDD WHERE EEE='100001' "); # 実行 $nRes = $hSt->execute; # データ取得 while($raRes = $hSt->fetchrow_arrayref) { print join(",", @$raRes), "\n"; #","区切りで出力 } #実行すると DBD::Oracle::db do failed: ORA-00922: ??????????????????????? (DBD ERROR: error possibly near <*> indicator at char 4 in 'set <*>names 'ujis'') [for statement ``set names 'ujis''']) at ./test.pl line 18. ,???????,ABC,??? ??152 ,???? ,??????????123,03-xxxx-xxxx ... #表示された内容部分はもっと多くのデータでしたが省略してあります と、散々な結果でした・・・(;^_^ A どなたか解決方法を教えていただけますか? あ、最後になりますが環境です。 サーバ: Oracle9 Perl5.8.0 ソース全体は以下のtxtファイルを参照してください。 ttp://briefcase.yahoo.co.jp/bc/urd_apple/

  • Perl
  • 回答数3
  • ありがとう数3

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

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

perl5.8で、DBI+DBD-ORACLEが動作したっけ? っていう疑問はあるんですが、きっと今は動くのですよね。 >$dbh->do("set names 'ujis'"); オラクルは、そのようなSQLを投げられても処理できません。 今は、これが邪魔してエラーになっています。 基本的に、オラクルサーバ-クライアントの文字コード処理は、NLSが自動で行います。 perlが動作する環境のNLS_LANGに従って変換された日本語文字が受け取れる仕組みです。 (文字コードがあっているかどうかはともかく、それで受け取れる) もし、オラクルクライアントの設定と違った文字コードで無理矢理受け取りたいなら、 コネクト前に、 $ENV{'nls_lang'}="JA16SJIS"; とか $ENV{'nls_lang'}="JA16EUC"; とすれば、SJISやEUCで受け取れるハズです。 他にも、SQL文の投入でも一時的変更は可能なハズですが。

urdapple
質問者

お礼

回答ありがとうございますm(_ _)m osamuyさんやkorochanさんの言われる通り、Oracleから持ってきたデータがTelnet上で化けているというのはNLS_LANGのせいでした。 本当にありがとうございました。 Telnet上で export NLS_LANG=japanese.JAPAN.JA16SJISTILDE とすることで、一時的にクライアント側のNLS_LANGを書き換えたら問題なくSJISで行けました。 とりあえず.bash_prof(だったかな?)にその旨書き込んで、毎回問題なくTelnet接続でいろいろやれております。 お騒がせしました。ありがとうございましたm(_ _)m

その他の回答 (2)

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.2

Oracleなら、環境変数NLS_LANGを指定してみては。 > set names 'ujis' は、MySQLの作法みたいですが。

参考URL:
http://ash.jp/db/ora_nls.htm
urdapple
質問者

お礼

回答ありがとうございます。 そうですか... 「set names 'ujis'」は、MySQLの作法ですか... ...って恥ずっ!! そんなことさえも知らなかった(汗 環境変数ってことは、Oracle側での設定なんですかね?それともPerl文内でsql文を実行して設定できるものなのかしらん... ちょっと調べてみます。

urdapple
質問者

補足

そもそも基本的にOracle側をこちらでいじることができないんです(T-T) しかも以下のページにある通り、サーバ自体を再起動的な方法は、権限として与えられていないのでどうにもこうにも... http://ml.php.gr.jp/pipermail/php-users/2003-August/018035.html

  • agharta
  • ベストアンサー率52% (54/103)
回答No.1

とりあえず、変数の中身はUTFのままで、出力する際に希望のコードに変更してみては如何ですか。 Jcode.pm等が使えれば、プログラムの最初の方で use Jcode; として、$pre_strの文字列をeucに変更するには my $after_str = Jcode->new($pre_str)->euc; 等とすればいいのではないでしょうか。 また、fetchrow_arrayrefはリターン値がリファレンスの配列です。 すなわち、ここで言うところの$raResはリファレンスです。 使い方としては、$raRes->{"column_name"}ではないでしょうか。 この例だとDDDテーブルにおいてEEEカラムが'100001'の全てのカラムを出すと言うことですよね。少なくともカラム名がEEEなので$raRes->{"EEE"}と言うように使います。 もしくは、fetchrow_arrayを使用するかですね。 参考になれば良いのですが…

urdapple
質問者

お礼

回答ありがとうございます。 社内での出来事でしたので、今現在作業できませんが、来週早速試してみます。(家に同じ環境があればイイんですが、そんな・・・Oracleなんて買えないし・・・( ̄▽ ̄;)) あ、ちなみにモジュールではなくjcode.plは管理者に入れてもらってあるのですが、そっちを使うことも可能ですか? さらに・・・ >また、fetchrow_arrayrefはリターン値がリファレンスの配列です。(以降) DB関係ズブの素人なので、チンプンカンプンです(T^T)(これから勉強してみます) ごめんなさい。このスクリプトもDBとの接続やらデータの取得やらに関しては、他人のスクリプトの流用なので・・・(恥)

urdapple
質問者

補足

(T-T)ダメでしたぁ... jcode.plは置いてあるので、それを使用して... 18 while(@row = $sth->fetchrow_array) 19 { 20 @before_str = @row; 21 print "@row\n"; 22 } 23 24 my $str_code = jcode::getcode($before_str[16]); 25 my $after_str = jcode::convert($before_str[16]); 26 print $before_str[16],"\n"; 27 print $str_code,"\n"; 28 print $after_str,"\n"; #$before_str[16]は、下の結果を見てもわかる通り「??????? 」と、確実に化けているデータを持つ変数です。 で、結果は... Use of uninitialized value in pattern match (m//) at ./jcode.pl line 362. Use of uninitialized value in pattern match (m//) at ./jcode.pl line 362. ??????? Use of uninitialized value in print at ./test2.pl line 27. Use of uninitialized value in print at ./test2.pl line 28. んで、結果からして「おそらく」というお話なんですが、Perl側のeuc-jpのソース上で、すでに化けた状態でjcodeに渡されているために、正規表現のパターンに引っかかっていないんだと思うんですよね。 なので、最初から化けないようにデータを持ってくる必要がありそうなんですが... Perl文上から何かsql文を発行して、持ってくる段階で化けないようにする方法ってないものですかねぇ?

関連するQ&A

  • PerlからOracleに接続

    ご存知の方おられましたら、ご教示お願い致します。 昨日より、Perlのプログラムを始め、Oracleに接続するものを作成しておりまが以下のエラーがでてきて困っております。 接続部分ソース--------------------------- #!C:\パス use DBI; $dbh = DBI->connect("dbd:Oracle:データベース名", "ユーザ","パスワード"); エラー----------------------------------- install_driver(Oracle) failed: Can't locate loadable object for module DBD::Orac le in @INC (@INC contains: C:/Program Files/Perl/lib C:/Program Files/Perl/site/ lib .) at (eval 1) line 3 Compilation failed in require at (eval 1) line 3. Perhaps a module that DBD::Oracle requires hasn't been fully installed at database.pl line 5 環境--------------- OS WindowsXP pro perl ActivePerl-5.8.6.811 DBI,DBDはPPMでインストールしました。 接続先 OS Windows2003 DB oracle9 後、 use DBI; @ary = DBI->available_drivers; foreach (@ary){ print $_,"\n"; } でDBI使用できるDBDドライバを出した結果、Oracleが表示されておりました。 どうか、ご存知の方お願い致します。

  • Oracleのデータベースに接続できない。

    OS : WindowsXP SP2 Perl : ActivePerl 5.8.8 DBD : DBD-Oracle1.17 DB : Oracle9i PerlでOracleのDBサーバに接続ができません。 ソースは以下の通りです。 ================================================================================ #!perl -w use DBI; $dbh = DBI->connect('dbi:Oracle:test', 'scott/tiger') or die "An error occured : $@"; $dbh->disconnect; exit 0; ================================================================================ 上記コードを実行すると、connectの行でdieします。 ================================================================================ D:\test>perl ttoracle.pl DBI connect('test','scott/tiger',...) failed: ORA-12705: Cannot access NLS data files or invalid environment specified (DBD ERROR: OCISessionBegin) at ttoracle.pl line 5 An error occured : at ttoracle.pl line 5. ================================================================================ Oracleのサーバーはローカルにあり、ポートもデフォルトの設定です。 試しに、 $dbh = DBI->connect('dbi:Oracle:test@localhost:1521', 'scott/tiger') or die "An error occured : $@"; としましたが、結果は同じでした。 また、エラーの内容的に環境変数かと思いORACLE_HOMEを環境変数にセットしてみましたが、これもまた、結果は同じでした。 DBの接続については、sqlplusコマンドからであれば問題なく接続できます。 (コマンド:sqlplus scott/tiger@test) やはり、環境変数まわりの設定が問題でしょうか? よろしくお願いします。

  • Oracleデータベースに接続

    いつもお世話になります。 DBD-Oracleモジュールを使用して接続を試みているのですが、以下のエラーになります。 「プロシージャエントリポイントPL_memory_wrapがperl58.dllからみつかりません」 とダイアログが表示され、 install_driver(Oracle) failed: Can't load 'C:/Perl/site/lib/auto/DBD/Oracle/Oracle.dll' for module DBD::Oracle: load_file:指定されたプロシージャが見つかりません。 at C:/Perl/lib/DynaLoader.pm line 230. at (eval 1) line 3 Compilation failed in require at (eval 1) line 3. Perhaps a required shared library or dll isn't installed where expected at test.pl line 16 とメッセージがでます。 スクリプトは以下です。 $hDB = DBI->connect("dbi:Oracle:host=$host;sid=$sid", $user, $passwd); $hSt = $hDB->prepare("SELECT * FROM emp"); $nRes = $hSt->execute; while(@aRes = $hSt->fetchrow) { print join("\t", @aRes), "\n"; } $hSt->finish; $hDB->disconnect; 環境: Windows2000Server ActivePerl 5.8.6 Oracle8i どなたかわかる方おりましたら、ご教示下さい。。宜しくお願い致します。

    • ベストアンサー
    • Perl
  • Oracle-Perlの接続

    Oracle と Perl の接続で悩んでいます。 申し訳ありませんが何方かご教授下さい。 OS:Red Hat Enterprise Linux ES release 4 Perl:perl v5.8.5 DB:oracle-xe-univ-10.2.0.1-1.0.i386 ドライバーは以下をインストールしてあります。 perl-DBD-Pg-1.31-6 perl-DBD-MySQL-2.9004-3.1 perl-DBI-1.40-8 以下もインストールしてみましたが駄目でした # rpm -ivh oracle-instantclient12.1-basic-12.1.0.1.0-1.i386.rpm # rpm -ivh oracle-instantclient12.1-devel-12.1.0.1.0-1.i386.rpm # rpm -ivh oracle-instantclient12.1-sqlplus-12.1.0.1.0-1.i386.rpm 環境変数の設定(.bash_profileに以下を設定) . /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/bin/oracle_env.sh Perlでサンプルプログラムを作成して、他の同等のサーバでは正常に動作確認した プログラムを、このサーバで実行すると以下の様なエラーが出ます。 [oracle@IJYOU]$ perl test_db.pl install_driver(Oracle) failed: Can't locate DBD/Oracle.pm in @INC (@INC contains: /usr/lib/perl5/5.8.5/i386-linux-thread-multi /usr/lib/perl5/5.8.5 /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.4/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.3/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.2/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.1/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl/5.8.4 /usr/lib/perl5/site_perl/5.8.3 /usr/lib/perl5/site_perl/5.8.2 /usr/lib/perl5/site_perl/5.8.1 /usr/lib/perl5/site_perl/5.8.0 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.4/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.3/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.2/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.1/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl/5.8.4 /usr/lib/perl5/vendor_perl/5.8.3 /usr/lib/perl5/vendor_perl/5.8.2 /usr/lib/perl5/vendor_perl/5.8.1 /usr/lib/perl5/vendor_perl/5.8.0 /usr/lib/perl5/vendor_perl .) at (eval 1) line 3. Perhaps the DBD::Oracle perl module hasn't been fully installed, or perhaps the capitalisation of 'Oracle' isn't right. Available drivers: ExampleP, Pg, Proxy, mysql. at /home/oracle/test2_setting.pl line 18 どうか何方かお願いします。

  • MySQL 文字化けについて(PHP)

    いつもお世話になっております。 PHPを使用してMySQLからデータを出し入れする際に文字化けが発生し原因がわからず、大変困っております。 MySQL 4.1.18(クライアント 4.1.21) MySQL文字セット UTF-8 Unicode (utf8) 様々なHPを検索して、下記のような一文を入れれば大丈夫と思ったのですが、それでも文字化けは改善されませんでした。 mysql_query("SET NAMES ujis"); 上記文はmysql_connectの直後に記述しております。 INSERT文、SELECT文どちらに不備があるのかわかりません。 ご教授お願い致します。 記述プログラム:(INSERT文) /********************************* * MySQL接続 ********************************/ // DB Connect $db = db_connect(); // DB Select select_db($db); // Set Names mysql_query("SET NAMES ujis"); /********************************* * INSERT文 ********************************/ $sql = "insert into T_YOYAKU values ('1','A','1','あいうえお')"; mysql_query($sql) 省略・・・ 記述プログラム:(SELECT文) /********************************* * MySQL接続 ********************************/ // DB Connect $db = db_connect(); // DB Select select_db($db); // Set Names mysql_query("SET NAMES ujis"); /********************************* * INSERT文 ********************************/ $sql = "select * from T_YOYAKU"; if ( $rs = mysql_query($sql) ) {

    • ベストアンサー
    • MySQL
  • Perl+DBD::Oracleのエラーがわからず困っています

    jboss と申します。お世話になります。 Solaris 上で動作させていた cgi プログラムを Linux へ移行しています。 下記の動作環境にて、ブラウザより該当プログラムを実行すると、 下記のようなエラーが発生します。 ■ 動作環境 OS RedHatLinux EL4.0 Apache 1.3.37 Perl 5.8.5 DBI 1.52 DBD::Oracle 1.18 DB Oracle 8i (8.1.7) ■ Apache のエラーログ install_driver(Oracle) failed: Can't load '/usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi/auto/DBD/Oracle/Oracle .so' for module DBD::Oracle: libclntsh.so.8.0: cannot open shared object file: No such file or directory at /usr/lib/per l5/5.8.5/i386-linux-thread-multi/DynaLoader.pm line 230, <DATA> line 855. at (eval 7) line 3 Compilation failed in require at (eval 7) line 3, <DATA> line 855. Perhaps a required shared library or dll isn't installed where expected at /export/home/orasql.pl line 30 エラーログから解決方法を検索して、下記の方法は試したのですが解決しません。 ・LD_LIBRARY_PATH の追加 ・libclntsh.so.8.0 のパーミッション変更 ご存知であればご教授の程、お願い致します。

  • PerlからDBの接続

    やまとです。こんにちは。 PerlからDBに接続しているのですが、うまく出来ません。 環境は OS : Windows2000、Perl : ActivePerl628、DB : Sybase11.0.3 DBI : DBI1.18、DBD : DBD_Sybase です。 DBDとDBIインストール後、DBに接続するとエラーが起こります。 エラーが起こる場所は(ソース抜粋記載) use DBI; (←ここは平気) $dbh=DBI->connect($database, $db_user, $db_password) or return 0;      (↑ここがエラー) 以上の箇所です。 もちろん、$database, $db_user, $db_passwordそれぞれの変数には 正しい値が入っています。 次にerror.logの内容ですが、 1つ目は、 Premature end of script headers: C:\・・・・・・・(←実行ファイル名) 2つ目は、 install_driver(Sybase) failed: DBD::Sybase initialize: cs_ctx_alloc() failed at C:/Perl/lib/DynaLoader.pm line 225. 3つ目は at ./test.cgi line 43 (←connectの場所) となっております。 色々調べてみましたが、分かりませんでした。 use DBI; は正常に動作していますので、DBDとDBIのインストールは正常に 出来ていると思うのですが・・・ 同じ経験、又は、このエラーに関して分かる方いらっしゃいましたら、 対処法、ご教授願いたいのですが。 宜しくお願いします。 #環境の情報など不足している部分がありましたら補足させて頂きます。

    • ベストアンサー
    • Perl
  • Shift-JIS文字化けについて

    shift-jisで作成したcsvを、MySQLへ"load data infile"し、perlにて query("select * from... ) で検索一致したものを、 "Content-type: text/html;charset=Shift_JIS\n\n"のHTMLで表示させたところ、???と表示され、文字化けしてしまっております。日本語が入る部分のcreateした型はtext型です。 しかし、"Content-type: text/html;charset=EUC-JP\n\n"ですと、正しく検索され、日本語表示されてました。このままEUCでいきたいところですが、作業の都合上、HTMLをsjisで表示させなければならず対策に行き詰っております。 環境ですが、レンタルサーバのRedHat(versionは失念...)、MySQLのcharsetは、 mysql>show variables like 'char%'; character_set_client ujis character_set_connection ujis character_set_database ujis character_set_results ujis character_set_server ujis character_set_system utf8 perl, MySQLのバージョンは以下です。 o perl-5.8.0-88.4 o mysql --version Ver 14.7 Distrib 4.1.14, for pc-linux-gnu (i686) using EditLine wrapper レンタルサーバである事と、別の運用中サーバが既にMySQLを利用中であるため、再コンパイルをせずに、影響が無い範囲でどうにか日本語文字化けを改修できないか、過去の本サイトの過去質問も読み返しまして、 変換ライブラリjcode::convert(\$str,'sjis','euc') や、perlスクリプトのDB connect直後に、 query("set names sjis") query("set character set sjis") なども行いましたが症状は変わらず、まだ解決に至っていない次第です。 #過去質問の見落としかもしれません。。。 何卒ご教授よろしくお願いします。m(_ _)m 情報の不足があればご指摘下さい。

    • ベストアンサー
    • MySQL
  • perlのdbi-connect処理のエラー

    active perlでdbi-connect処理から戻ってきません。教えてください。 以下のテスト的なプログラムで試しました。 Xには、数字が入ります。(会社のファイルサーバーになります) DBI->connectから戻ってきていないようです。(hhhhhhhhが表示されません) ちなみにDBI->connectをコメントにすれば表示されます。 申し訳ありませんが、どなたかご存知の方いらっしゃらないでしょうか? エラーがかえってこないと、何が悪いかわかりません。 困っています、宜しくお願いします。 ちなみにPerlは、Ver. 5.8.7.813でdbi,dbd-oracleは、昨日ppmでダウンロードしました。 # DBへコネクトする my $datasource = 'dbi:oracle:usrDB:xxx.xxx.x.xx:8080' ; my $usr = 'usrname' ; my $pass = 'usepass' ; my $dbh = DBI->connect($datasource,$usr,$pass) ; print "hhhhhhhhhhhh\n" ; if( ! $dbh ){ print "gggggggggggg\n" ; } $dbh->disconnect();

    • ベストアンサー
    • Perl
  • 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"; } ---------------

専門家に質問してみよう