mysql:8949
From: Hiroaki Sengoku <Hiroaki Sengoku <sengoku@xxxxxxxxxx>>
Date: Thu, 11 Mar 2004 12:08:58 +0900
Subject: [mysql 08949] sjis & BLOB
仙石と申します。既知の問題とは思いますが、あまり知られていない問題である ような気もしますので、まとめとして報告します。 default-character-set=sjis としていると、 BLOB 型のデータを挿入/更新する時、 0x81 〜 0x9F ないし 0xE0 〜 0xFC の次に エスケープ文字が来ても無視される という問題が、MySQL サーバにあります。4.0.16, 4.0.18, 4.1.1 で確認しました。 sjis だけでなく、症状から言って他のマルチバイト言語に共通する問題でしょう。 次の perl スクリプトで簡単に検証できます: ------------------------------------------------------------------------ #!/usr/bin/perl for ($i=112; $i < 256; $i++) { $sql .= sprintf("%c\\0", $i); } $sql = "INSERT INTO blobtest(data) VALUES ('$sql')"; use DBI; $db_url = "dbi:mysql:test:localhost"; $db_user = 'test'; $db_password = 'xxxxxxxx'; $dbh = DBI->connect($db_url, $db_user, $db_password, { PrintError => 1, RaiseError => 0 }); if (!defined($dbh)) { print "[NG] connect:\t" . $DBI::errstr; exit 1; } $sth = $dbh->prepare($sql); if(!($rv = $sth->execute())){ print "[NG] execute:\t$rv:$dbh->err:$dbh->strrstr:$dbh->state\n"; exit(1); } ------------------------------------------------------------------------ このスクリプトを走らせると、 ○\0○\0○\0○\0○\0... ( ○ は 0x70 〜 0xFF ) といった感じのデータを blobtest テーブルに挿入するわけですが、 ○が、0x81 〜 0x9F ないし 0xE0 〜 0xFC の範囲にある文字の時だけ、 その次の「\」が通常の文字と解釈されてしまい、 「\0」の部分が 0 という NULL 文字ではなく「\0」という文字列として 挿入されてしまいます。 症状から言って原因は明らかで、BLOB 型なのにリテラルを SJIS 文字列として 解釈してしまっているからでしょう。実際 4.0.x のソースコードでは、リテラ ルを default-character-set な文字列であると決めうちしてしまっています。 4.1.x では、カラムごとに character-set を切り替えられるようですが、 default-character-set=sjis していると、SJIS として解釈されてしまうようで す。_binary'○\0○\0○\0○\0○\0...' とすればいけそうな気がしたのですが、 4.1.x の機能を私がまだあまり理解できていないためか、今のところうまくいっ てません。 BLOB って (どちらかと言えば) 敬遠されているような気配も感じますが ;-)、 Java の場合は、NULL 文字等のエスケープを JDBC がやってくれるので、 byte[] data; ... pstmt = con.prepareStatement("INSERT INTO blobtest(data) VALUES (?)"); ... pstmt.setBytes(1, data); pstmt.execute(); などとそのまま setBytes できて簡単だし、(多少?) 遅いという欠点も BLOB 型 カラムを検索キーにするわけじゃないので、更新頻度が高くなければ充分使える ものだと思っています。 ただ、上記のように default-character-set=sjis している場合は一筋縄にはい かないので、どうするのが一番スマートなのかと、悩んでいる今日このごろです。 #8793. 仙石 浩明 http://www.gcd.org/sengoku/ Hiroaki Sengoku <sengoku@xxxxxxxxxx>
-> 8949 2004-03-11 12:08 [Hiroaki Sengoku <sen] sjis & BLOB 8951 2004-03-11 16:22 ┗[<gcd00051@xxxxxxxxxx]