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
関連リンク
キャラクタセットを指定しても binary になってしまうことが分かった。 こういう時は本家のサイトを調べるべきである。 MySQL Lists(メーリングリスト)、 バグ情報などを調べる必要があろう。
バグ情報の中の 1/10に登録された CHARACTER SET still not working in stored functionsによると、
ファンクションは、戻り値のキャラクタセットに utf8 をしているにも拘らず、 binaryになっている。そして、プロシージャの方で、OUT により出力指定した パラメーターのキャラクタセットは、ちゃんとutf8になっているとのことだ。 バージョンは、5.0.19-BK, 5.0.18 でこのバグが確認されている。
ということで、まだ5.0.18に対してマニュアルに加えられたことは、 実は動いていないらしい。 つまり、
文字型のファンクションのキャラクタセットは、勝手にbinaryになる
ということだ。これはバグで、対応してくれるようだ。
今すぐに使うには、どうすれば良いか
正しく動かないけれども、それでも今すぐにファンクションで 日本語文字列を返したい場合、どうすれば良いだろうか。
ここで、逆転の発想をしてみよう。
キャラクタセットとして、binaryを指定してみよう。
どのキャラクタセットであっても、binaryに変換するときには、 文字列そのもの、要するにバイト列の内容は変らないのを憶えているだろうか。 binaryにすることで、予期しないキャラクタセットの変換がかかっていたのを、 止めさせようという魂胆である。
mysql> DROP FUNCTION IF EXISTS hello;
Query OK, 0 rows affected (0.20 sec)
mysql> DELIMITER //
mysql> CREATE FUNCTION hello() RETURNS VARCHAR(50) CHARACTER SET binary
-> DETERMINISTIC RETURN 'こんにちは';
-> //
Query OK, 0 rows affected (0.01 sec)
mysql> DELIMITER ;
mysql>
では、hello() をSELECTして確認してみよう。
mysql> SELECT hello(); +------------+ | hello() | +------------+ | こんにちは | +------------+ 1 row in set (0.05 sec) mysql> SELECT CHARSET(hello()); +------------------+ | CHARSET(hello()) | +------------------+ | binary | +------------------+ 1 row in set (0.00 sec) mysql>
binaryになっているが、ちゃんと表示ができている。
もうちょっと、複雑な使い方をしてみよう。
mysql> SELECT CONCAT('東京より、',hello(), '、MySQLだよ' );
+----------------------------------------------+
| CONCAT('東京より、',hello(), '、MySQLだよ' ) |
+----------------------------------------------+
| 東京より、こんにちは、MySQLだよ |
+----------------------------------------------+
1 row in set (0.00 sec)
mysql>
でも、hello() がbinaryなので、
mysql> SELECT CHARSET(CONCAT('東京より、',hello(), '、MySQLだよ' ));
+-------------------------------------------------------+
| CHARSET(CONCAT('東京より、',hello(), '、MySQLだよ' )) |
+-------------------------------------------------------+
| binary |
+-------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
CONCATした結果のキャラクタセットはbinaryになってしまう。 これを避けるには、hello()に対して、CONVERT関数により本来のキャラクタセット に変換してしまえば、以下のように全体のキャラクタセットも正常なものになる。
mysql> SELECT CHARSET(CONCAT('東京より、',CONVERT(hello() USING eucjpms),'、MySQLだよ'));
+----------------------------------------------------------------------------+
| CHARSET(CONCAT('東京より、',CONVERT(hello() USING eucjpms),'、MySQLだよ')) |
+----------------------------------------------------------------------------+
| eucjpms |
+----------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
しかし、さすがにこんな書き方はしたくないものだ。 あくまでも、今すぐに何とか使いたいという場合の 苦肉の策、急場しのぎ、誤魔化しである。
この問題は、日本語だけでなく、あらゆる言語で色々影響があるので、 近々直るのではないかと思う。直ったところで、再訪しようかと思う。
フィードバック:
There is no comment.