
初投稿になります。過去ログを検索したのですが、似た質問はあるものの根本的な解決につながらなかったので、新規の投稿をさせていただきました。
乱文ご容赦ください。
今現在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/
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文の投入でも一時的変更は可能なハズですが。
回答ありがとうございますm(_ _)m
osamuyさんやkorochanさんの言われる通り、Oracleから持ってきたデータがTelnet上で化けているというのはNLS_LANGのせいでした。
本当にありがとうございました。
Telnet上で
export NLS_LANG=japanese.JAPAN.JA16SJISTILDE
とすることで、一時的にクライアント側のNLS_LANGを書き換えたら問題なくSJISで行けました。
とりあえず.bash_prof(だったかな?)にその旨書き込んで、毎回問題なくTelnet接続でいろいろやれております。
お騒がせしました。ありがとうございましたm(_ _)m
No.2
- 回答日時:
Oracleなら、環境変数NLS_LANGを指定してみては。
> set names 'ujis'
は、MySQLの作法みたいですが。
参考URL:http://ash.jp/db/ora_nls.htm
この回答への補足
そもそも基本的にOracle側をこちらでいじることができないんです(T-T)
しかも以下のページにある通り、サーバ自体を再起動的な方法は、権限として与えられていないのでどうにもこうにも...
http://ml.php.gr.jp/pipermail/php-users/2003-Aug …
回答ありがとうございます。
そうですか...
「set names 'ujis'」は、MySQLの作法ですか...
...って恥ずっ!!
そんなことさえも知らなかった(汗
環境変数ってことは、Oracle側での設定なんですかね?それともPerl文内でsql文を実行して設定できるものなのかしらん...
ちょっと調べてみます。
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を使用するかですね。
参考になれば良いのですが…
この回答への補足
(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文を発行して、持ってくる段階で化けないようにする方法ってないものですかねぇ?
回答ありがとうございます。
社内での出来事でしたので、今現在作業できませんが、来週早速試してみます。(家に同じ環境があればイイんですが、そんな・・・Oracleなんて買えないし・・・( ̄▽ ̄;))
あ、ちなみにモジュールではなくjcode.plは管理者に入れてもらってあるのですが、そっちを使うことも可能ですか?
さらに・・・
>また、fetchrow_arrayrefはリターン値がリファレンスの配列です。(以降)
DB関係ズブの素人なので、チンプンカンプンです(T^T)(これから勉強してみます)
ごめんなさい。このスクリプトもDBとの接続やらデータの取得やらに関しては、他人のスクリプトの流用なので・・・(恥)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- MySQL 参考書に従って入力したつもりでしたが、最後はエラーがでました。 1 2022/09/28 03:45
- Perl Perlのエラーについてご教授ください。初心者です。 CGIを別サーバに移したところ、Perlのバー 5 2023/05/31 10:48
- PHP php my adminより取り出したデータ表示 2 2022/06/15 11:56
- PHP クエリObjectをforeachで回す時に、次のレコードへ移動せずに次のレコードを取得したい 2 2022/07/28 15:29
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
- Visual Basic(VBA) VBAでの共有パスにつきまして 1 2023/03/04 17:24
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- Excel(エクセル) EXCELの外部データ取得ができない 1 2023/03/23 09:03
- その他(プログラミング・Web制作) pythonのWebスクレイピングでfind_allだとurlがNoneに 4 2022/04/17 18:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語の問題について
-
DOSコマンドで、標準出力を出力...
-
「print関数は出力先のファイル...
-
Perlでファイルの末尾から指定...
-
EUCで出力されるプログラムをS-...
-
ファイルからある文字列の個数...
-
DBMとハッシュ
-
エクセルVBA コードが同じでも...
-
readdir()で得られるファイル・...
-
Perl で ディレクトリ及びサブ...
-
batファイルでrenameができませ...
-
Perlの変数に文字数制限(容量...
-
requireで同じライブラリを複数...
-
perlの無名配列の使い方を教え...
-
ReadLineでの読み出し行を指定する
-
「パスが見つかりません」とい...
-
C言語で特定の行を抽出する方法...
-
VBAでCSVファイルを途中行まで...
-
シェルスクリプトについて
-
CSVファイルのフォーマット
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
重複するデータを抽出できる秀...
-
awkスクリプトでダブルクォーテ...
-
sprintfについて
-
DOSコマンドで、標準出力を出力...
-
文字コードの変換(Shift-JISか...
-
Perl<->Oracle間での文字化けに...
-
[Perl]ファイル出力のエンコー...
-
エクセルVBAで素数だけを出力す...
-
データの選択
-
apacheの動作について
-
「print関数は出力先のファイル...
-
教えて!perlから.exeファイル...
-
ファイル出力の改行コードをLFに
-
PerlからのCSV出力
-
Active Perlでsleepを使う。
-
[awk]uniq -cで複数ファイルの...
-
バッチファイルで、記号を含む...
-
EUCで出力されるプログラムをS-...
-
htmlから、ファイル、もしくはC...
-
リファレンスについて。
おすすめ情報