[pgsql-jp: 25211] Re: Windows上JDBC でのエンコーディング

TANAKA Yoshihiro ytp @ vc-net.ne.jp
2002年 3月 11日 (月) 10:36:44 JST


田中 良浩 です。

★Javaでない皆さんには申し訳ありません。

On Mon, 11 Mar 2002 09:02:28 +0900
Tsunehisa Kazawa <kazawa @ sons.co.jp> wrote:

>加澤と申します。横からすみません。

初めまして、よろしくお願いします。

>Java を使って開発を行っている者としての意見です。

文字化けの経験はお持ちですか?

>YTP wrote:
>> 田中良浩 です。
>[省略]
>> 最初に結論を申し上げますと、
>> Postgreが提供するJDBCの内部でのデコードは、
>> プラットフォームに合わせたデフォルトエンコーディングを使って
>> 処理するようにはできないでしょうか、ということなんです。
>> (現状では、サーバ上のエンコーディング指定で決め打ちしている
>> ように見え、結果的にSJISになってしまうと思います)
>
>これは逆ではないでしょうか?RDBMS のようにさまざまなシステム、
>OS から利用されることが想定されるようなシステムでは、クライア
>ントサイドのデフォルトエンコーディングは使うべきではないと思い
>ます。EUC-JP などとの相互変換のことを考えても SJIS コンバータ
>固定の方が設計として望ましいのでは?

RDB内データのエンコーディングのことではありません。
そこから読んで来たデータをアプリケーションに渡す時の話です。

論より証拠ですよね...
実験してみました。

■環境(最初のメールと同じ)
・サーバ
  +TurboLinux 6.0
  +PostgreSQL7.2
  +initdbは"EUC_JP"で設定 ★
・クライアント
  +Windows2000 Professional
  +JDK1.4
  +JDBCドライバはhttp://jdbc.postgresql.org/download.html から入手
   (7.2対応版)

■DBエンコーディング
        List of databases
   Name    |  Owner   | Encoding
-----------+----------+----------
 begin     | postgres | EUC_JP
 
■コンソールエンコーディング
export PGCLIENTENCODING=SJIS

■DB
begin=> select * from product;
 pcode |     pname      | price
-------+----------------+-------
 P001  | カーネーション |   120
 P002  | かすみ草       |    80
 P003  | バラ           |   180
 P004  | 桃の花         |   480
 P999  | 東京〜新大阪   | 12160
(5 rows)
上記は、TeraTermの設定をSJISにして採取
★当然ですがこの時点で文字化けはありません。

■テストプログラム
package ytp.test;

import java.sql.*;
import java.util.*;

public class TestPostgre {
    private Connection con_ = null;
    private Statement stmt_ = null;
    
    public static void main(String[] args) {
        TestPostgre test = new TestPostgre();
        test.test(args);
    }
    
    public void test(String[] args) {
        try {
            Class.forName("org.postgresql.Driver");
            con_ = DriverManager.getConnection(
                  "jdbc:postgresql://atak:5432/begin", "ytp", "");
            System.out.println("encoding on PC="
             + ((org.postgresql.Connection)con_).getEncoding().name());
            stmt_ = con_.createStatement();
            ResultSet rs = stmt_.executeQuery("select * from product");
            
            while (rs.next()) {
                System.out.println(rs.getString("pname"));
            }
            stmt_.close();
            con_.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

■テスト結果(文字化け)
C:\Source\Java>java ytp.test.TestPostgre
dbEncoding=SJIS encoding=SJIS
encoding on PC=SJIS
カーネーション
かすみ草
バラ
桃の花
東京?新大阪

■Encodingクラスの修正
org.postgresql.core.Encodingクラスの
encodings.put("SJIS", new String[] { "SJIS" });
を  ↓
encodings.put("SJIS", new String[] { "MS932" });
に変更します。

C:\Source\Java>javac org\postgresql\core\encoding.java

C:\Source\Java>java ytp.test.TestPostgre
dbEncoding=SJIS encoding=MS932
encoding on PC=MS932
カーネーション
かすみ草
バラ
桃の花
東京〜新大阪

C:\Source\Java>

※尚、テスト結果の表示でエンコーディングタイプを表示しているのは
ConnectionクラスでDBサーバのエンコーディングを取得した後に
String dbEncoding = resultSet.getString(2);
encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet"));
→System.out.println("dbEncoding=" + dbEncoding + " encoding=" + encoding.name());
と入れています。

いかがですか、"SJIS"エンコーディングだと化けますよね?
Javaな方にはご自分の環境で確認していただければ、と思います。

★メールをいただいても、本日は仕事の都合で
私から返信出来ないかもしれません。
申し訳ありませんが後日返事させていただきます。
------------------------------------
      田中 良浩(TANAKA Yoshihiro) / 日本インターシステムズ(株)
      E-mail:tanakay @ nisz.co.jp  -------------------------------






pgsql-jp メーリングリストの案内