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
関連リンク
REPLACE()で、普通の日本語文字列(eucjpms,cp932,utf8など)と、 binary文字列が3つのパラメータに混在していたとき、 結果の文字列がbinaryになることは分かった。
さて、唐突であるが、次のREPLACE()を考えてみよう。
mysql> SET NAMES eucjpms;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT REPLACE('東京理科大学','並','Physics');
+----------------------------------------+
| REPLACE('東京理科大学','並','Physics') |
+----------------------------------------+
| 東京理科大学 |
+----------------------------------------+
1 row in set (0.00 sec)
mysql>
'東京理科大学'という文字列の中には、'並'という文字列は存在しないので 置換は行なわれず、'Physics' という文字列は出力には現われない。
さて、ここで、最後のPhysicsだけをbinaryにしてみよう。
mysql> SELECT REPLACE('東京理科大学','並',_binary'Physics');
+-----------------------------------------------+
| REPLACE('東京理科大学','並',_binary'Physics') |
+-----------------------------------------------+
| 東京理?Physics膤? |
+-----------------------------------------------+
1 row in set (0.00 sec)
mysql>
すると、何だか置換が行なわれたようだ。 それも、何だか無理矢理行なったようで、文字の一部が壊れているようだ。
さて、'東京理科大学'というマルチバイト文字列の中には、 '並'という文字列は当然含まれていないので、置換されるのは変である。 ということは、この比較を行なう前に、実は全てのパラメータはbinary に変換されてしまい、そののちREPLACE()が実行されたのではないだろうか。
つまり、1つでもbinaryがあれば、
mysql> SELECT REPLACE(_binary'東京理科大学',_binary'並',_binary'Physics'); +-------------------------------------------------------------+ | REPLACE(_binary'東京理科大学',_binary'並',_binary'Physics') | +-------------------------------------------------------------+ | 東京理?Physics膤? | +-------------------------------------------------------------+ 1 row in set (0.00 sec) mysql>
と同じと考えて良いように思うがどうだろう。
REPLACE()は、 処理を始める前に、全てのパラメータが、結果のキャラクタセットに変換される。
ということらしい。
もちろん、
mysql> SELECT REPLACE(_binary'東京理科大学','並','Physics');
+-----------------------------------------------+
| REPLACE(_binary'東京理科大学','並','Physics') |
+-----------------------------------------------+
| 東京理?Physics膤? |
+-----------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT REPLACE('東京理科大学',_binary'並','Physics');
+-----------------------------------------------+
| REPLACE('東京理科大学',_binary'並','Physics') |
+-----------------------------------------------+
| 東京理?Physics膤? |
+-----------------------------------------------+
1 row in set (0.01 sec)
mysql>
となるのは予想通りである。
'東京理科大学'の中に'並'が存在する理由
この理由を調べるには、2つの文字列をHEX()を使って16進数表示してみればよい。
mysql> SELECT HEX('東京理科大学'), HEX('並');
+--------------------------+-----------+
| HEX('東京理科大学') | HEX('並') |
+--------------------------+-----------+
| C5ECB5FECDFDB2CAC2E7B3D8 | CAC2 |
+--------------------------+-----------+
1 row in set (0.00 sec)
mysql>
CAC2 という並びが、'東京理科大学' の中に存在するのが分かるだろう。 CA は'科'の第2バイト、C2は'大'の第1バイトである。
そして、binaryになってしまったら、マルチバイト処理は無視されて、 バイト単位の処理になってしまうので、binaryの'並'は'東京理科大学' の中に存在することになる。
mysql> SELECT HEX(REPLACE('東京理科大学','並',_binary'Physics')), HEX('Physics');
+----------------------------------------------------+----------------+
| HEX(REPLACE('東京理科大学','並',_binary'Physics')) | HEX('Physics') |
+----------------------------------------------------+----------------+
| C5ECB5FECDFDB250687973696373E7B3D8 | 50687973696373 |
+----------------------------------------------------+----------------+
1 row in set (0.00 sec)
mysql>
つまり、
マルチバイト文字列処理が、binary文字列処理をされると、 奇怪なことになることがある。
ということをしっかり記憶しておこう。
こういう分析に慣れておくと、日本語を扱っているときに奇妙な現象が発生しても、 うまく手なずけることができるようになるかもネ。
戻る:キャラクタセットがbinaryの文字列のREPLACEは
次へ:eucjpms,cp932,utf8混在のREPLACEは
フィードバック:
There is no comment.