Chat (Lingr.com)
Informaiton
Daily
Column
- MySQL日本語の旅(5/1)
- アクセス向上秘伝(5/9)
- 一風変ったHaskellλ門(6/13)
- SICP Answer Book (5/31) 問題3.26追加
Zope Solution
Extra
アーカイブ
OSS案内所
Site Info
関連リンク
前回の復習をしておこう。以下のように、〜 が ~ に化けたのであった。
mysql> SET NAMES ujis; Query OK, 0 rows affected (0.00 sec) mysql> SELECT '〜'; +-----+ | ~ | +-----+ | 〜 | +-----+ 1 row in set (0.00 sec)
原因を調べるには、16進数にしてみるに限る。
mysql> select hex('〜');
+----------+
| hex('~') |
+----------+
| 8FA2B7 |
+----------+
1 row in set (0.00 sec)
SET NAMES ujis としたので、これは ujis の文字を16進数表示したものである。 しかし、1文字しかないはずなのに3バイトになってしまった。
最初が 8F になっているので、これは JIS X 0212(補助漢字)ってことだ。 というわけで仕方なく補助漢字のテーブルを眺めたら、 02区23点に~が入っていた。これにされちゃったみたいである。
〜は、補助漢字ではなくて、JIS X 0208 の01区33点の方でなくてはならないのに、 勝手な解釈が行なわれてしまったようだ。この文字は、EUC-JPでは 16進数ではA1C1になる。
ということで、16進数で文字を指定してみよう。
mysql> SELECT _ujis 0x7E, _ujis 0x8FA2B7, _ujis 0xA1C1; +---+-----+----+ | ~ | ~ | 〜 | +---+-----+----+ | ~ | 〜 | 〜 | +---+-----+----+ 1 row in set (0.00 sec)
0x8FA2B7の方は怪しい動きをしてくれる。 0xA1C1の方は、どちらも〜になっているので問題なし。 sjisに変換するとどうなるか調べてみよう。
mysql> SELECT HEX(CONVERT(_ujis 0x8FA2B7 USING sjis)); +-----------------------------------------+ | HEX(CONVERT(_ujis 0x8FA2B7 USING sjis)) | +-----------------------------------------+ | 7E | +-----------------------------------------+ 1 row in set (0.00 sec)
なんと、単なる1バイトの 7E になってしまった。 utf8にするとどうなるか。
mysql> SELECT HEX(CONVERT(_ujis 0x8FA2B7 USING utf8)); +-----------------------------------------+ | HEX(CONVERT(_ujis 0x8FA2B7 USING utf8)) | +-----------------------------------------+ | 7E | +-----------------------------------------+ 1 row in set (0.00 sec)
やはり、7Eになってしまった。ついでに latin1 を試してみよう。
mysql> SELECT HEX(CONVERT(_ujis 0x8FA2B7 USING latin1)); +-------------------------------------------+ | HEX(CONVERT(_ujis 0x8FA2B7 USING latin1)) | +-------------------------------------------+ | 7E | +-------------------------------------------+ 1 row in set (0.00 sec)
これはすごいや。何で latin1 に変換できちゃうんだろう。
mysql> select HEX(CONVERT('〜' USING sjis));
+------------------------------+
| HEX(CONVERT('~' USING sjis)) |
+------------------------------+
| 7E |
+------------------------------+
1 row in set (0.00 sec)
'〜' は ujisとして MySQLサーバに渡され、そこで sjisに変換されると 1バイトの7Eになってしまった。
sjisは補助漢字はサポートできないので、 補助漢字として解釈された〜が、~(7E)にされてしまうのは仕方がない。 しかし、本来なら、ujisだろうがsjisだろうが JIS X 0208 にある、 普通に「から」の意味でよく使用される〜として解釈してくれないことには トラブルに陥る。
ということは、
mysql> select '〜' = '~'; +-----------+ | '~' = '~' | +-----------+ | 0 | +-----------+ 1 row in set (0.00 sec)
といういことで、 2つの文字列 '〜' と '~' は異なるという当然の結果になるのだが、 '〜' を sjis に変換してから比較すると
mysql> select CONVERT('〜' USING sjis) = CONVERT('~' USING sjis);
+---------------------------------------------------+
| CONVERT('~' USING sjis) = CONVERT('~' USING sjis) |
+---------------------------------------------------+
| 1 |
+---------------------------------------------------+
1 row in set (0.00 sec)
となり一致する。
つまり、ujis の '〜' と '~' が sjis に変換すると、どちらも同じ '~'(7E)に変換されてしまう。 要するに、ujis と sjis の文字が1対1対応していないのだ。
それにしても、何で〜を補助漢字にしてしまうんだ。 いったいどこからそんな馬鹿なことを考えついたんだろう。
〜 は補助漢字 …… そんな馬鹿な
\(5C)も1対1対応していない
\(5C)の場合についても同じテストをしておこう。
mysql> select CONVERT('\' USING sjis) = CONVERT('\\' USING sjis);
+----------------------------------------------------+
| CONVERT('\' USING sjis) = CONVERT('\\' USING sjis) |
+----------------------------------------------------+
| 1 |
+----------------------------------------------------+
1 row in set (0.00 sec)
まったく同じ結果になってしまった。やれやれ。
まいったなぁ、どうすればいいんだ。
フィードバック:
There is no comment.