[pgsql-jp: 35297] Re: IBM拡張文字の扱いについて

kk noritamag @ hotmail.com
2005年 4月 20日 (水) 12:00:05 JST


kkです。
小川様、石井様、森山様、レスありがとうございます。
できることから試しており、レスが遅くなりすみません。

# 一部改行箇所を変更させて頂いております
> IBM拡張文字の変換表は、postgresqlのソースコードに
> あります。src/backend/utils/conversion_procs/
> euc_jp_and_sjisの、sjis.mapです。
> 変換ルールを変えたい場合、sjis.mapを変更して
> postgresqlをコンパイルする必要があります。

早速、PostgreSQL7.4.3で試してみました。

【試したこと】
変更したのは、
/usr/local/src/postgresql-7.4.3/src/backend/utils/mb/
conversion_procs/euc_jp_and_sjis にある、sjis.mapです。

例えばfa40〜fa49について以下のように変更し、保存しました。

{       0xEEEF  ,       0xfa40   ,   0xfcf1     },
{       0xEEF0  ,       0xfa41   ,   0xfcf2     },
{       0xEEF1  ,       0xfa42   ,   0xfcf3     },
{       0xEEF2  ,       0xfa43   ,   0xfcf4     },
{       0xEEF3  ,       0xfa44   ,   0xfcf5     },
{       0xEEF4  ,       0xfa45   ,   0xfcf6     },
{       0xEEF5  ,       0xfa46   ,   0xfcf7     },
{       0xEEF6  ,       0xfa47   ,   0xfcf8     },
{       0xEEF7  ,       0xfa48   ,   0xfcf9     },
{       0xEEF8  ,       0xfa49   ,   0xfcfa     },

変更前の該当箇所は、参考までに以下の通りです。

{       0xEEEF  ,       0xfa40   ,   0x8ff3f3   },
{       0xEEF0  ,       0xfa41   ,   0x8ff3f4   },
{       0xEEF1  ,       0xfa42   ,   0x8ff3f5   },
{       0xEEF2  ,       0xfa43   ,   0x8ff3f6   },
{       0xEEF3  ,       0xfa44   ,   0x8ff3f7   },
{       0xEEF4  ,       0xfa45   ,   0x8ff3f8   },
{       0xEEF5  ,       0xfa46   ,   0x8ff3f9   },
{       0xEEF6  ,       0xfa47   ,   0x8ff3fa   },
{       0xEEF7  ,       0xfa48   ,   0x8ff3fb   },
{       0xEEF8  ,       0xfa49   ,   0x8ff3fc   },

その後、
# ./configure --enable-locale --enable-multibyte=EUC_JP --enable-odbc
# gmake
# gmake install

# mkdir /usr/local/pgsql/data
# chown hoge /usr/local/pgsql/data
# su hoge
% initdb -E EUC-JP -D /usr/local/pgsql/data
% postmaster  -i -D /usr/local/pgsql/data &
% createdb hoge_db

という流れでDBをつくり直しました。


【前準備と結果】
その1.
testtblテーブル(f1 varchar(5))をPostgreSQL
に作成し、0xfa40〜0xfa49 に相当する文字
(ローマ数字の1〜10)を、ODBCドライバ経由で
Accessリンクテーブルからインサートしました。

    ・Accessリンクテーブル経由で表示
     => 期待する表示(ローマ数字の1〜10)がされる

    ・phpでブラウザ表示
     => 文字化け(文字コード変換もされていない)
     (phpプログラムは長いのでメールの最後に載せます)

その2.
1とは逆に、
testtbl2テーブル(f1 varchar(5))をPostgreSQLに作成
→ Windows側でローマ数字の1〜10をテキストエディタに入力
→ ftpでバイナリ(sjis)でDB側にアップロード
→ Perlプログラムでsjis=>EUC変換
→ \copyでtesttbl2にインポート

    ・Accessリンクテーブル経由で表示
     => 文字化け(全て "・" で表示される)

    ・phpでブラウザ表示
     => ローマ数字の1〜10表示がされる


【期待した動作】
その1、その2共通:
    ・Accessリンクテーブル経由で表示
     => 文字化けしない

    ・phpでブラウザ表示
     => 文字化けしない


【疑問点】
sjis.map変更前は、
0xfa40 ⇔ 0x8ff3f
0xfa41 ⇔ 0x8ff3f4
と、sjis ⇔ eucJP-openで変換されていたことが
原因で文字化けが起きるのだと認識しておりました。

そこで、
0xfa40 ⇔ 0xfcf1
0xfa41 ⇔ 0xfcf2
と、sjis ⇔ cp51932で変換されるようにsjis.mapを
変更すれば、Accessリンクテーブル経由で入力した
特殊文字をphpでブラウザ表示させても、
逆に、0xfcf2(cp51932)の文字をAccessリンクテーブル
経由で表示させても化けないと思いました。

なにか検討違いのことをしておりますでしょうか?
また期待する動作(Accessリンクテーブル経由でも、
phpブラウザ表示でも、特殊文字が相互に化けない)
をさせるには、あと何が足りないのでしょうか?

[pgsql-jp: 35261]での、森山様のコメント、
「PostgreSQL を CP51932 に対応させた場合、PHP では
CP51932 に対応していないという事にご注意ください。」
が気になります。

それとも、
> ただし、この変換表は特定の範囲の文字コードに
> しか適用されませんので、変換表どおりに変換されない
> かもしれません。(拡張文字以外は変換表ではなく、
> 文字コードの計算で実行されます。)
> うまく変換できない場合、同ディレクトリにある
> euc_jp_and_sjis.cのsjis2mic関数や
> mic2sjis関数の変更が必要で、大変だと思います。

拡張文字についても一部しか、変換表に従って変換
されないのでしょうか?
まだ拡張文字の途中までしか、動作確認をしていない
ので。

度々お手数かけます。
以上、ご教示の程、よろしくお願い致します。


----- PHPのプログラム(文字および文字コードの表示) -----
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>ブラウザ表示テスト(eマネ)</title>
</head>

<body>
<h1>ブラウザ表示テスト(eマネ)</h1>
<p>

<?php

$DBHostName = "192.168.0.2";
$Port = "5432";
$DBName = "hoge_db";
$UserName = "hoge";
$Passwd = "hoge";

$con = pg_connect("host=$DBHostName port=$Port dbname=$DBName user=$UserName
password=$Passwd");
if (!$con) {
die("データベースに接続できませんでした。<br>\n");
}

$rs = @pg_query($con, "select * from testtbl");
if (!$rs) {
die("select できませんでした。<br>\n");
}

$maxrows = pg_num_rows($rs);
for ($i = 0; $i < $maxrows; $i++) {
$row = pg_fetch_row($rs, $i);
echo("$row[0]<br>\n");
echo bin2hex($row[0]) . "<br>\n<br>\n";
}
@pg_close($con);
?>
</p>
</body>
</html>



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