2009年4月17日

[mysql 14808] Re: SJISで文字コードがシフト?してしまい検索できない

坂井です

浅山さん。
現象の報告だけ書いて、どうしたらいいかを書いていませんでした。

さしあたって、もし要件上可能なら (たとえば "ビタミン"をマッチ
させたいカラムの)検索条件での UPPER( ) をはずせば期待通りの
動作になるかと思います。

テーブル定義をざっと見たところ varchar()カラムに binary が指定
されていないので大文字小文字を同一視してくれますから、upper()
を外しても問題ないように思えます。

例)先ほどの私のテストデータで:
mysql> select * from t WHERE a="abc";
+------+
| a |
+------+
| ABC |
| abc |
+------+
2 rows in set (0.01 sec)
upperなくてもマッチします。


それにしても、マニュアルにはこう書いてあるのにねぇ・・・:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_upper
>This function is multi-byte safe.


Thank you
On Fri, 17 Apr 2009 21:00:38 +0900
SAKAI Kei <sak2@xxxxx> wrote:
> 坂井です。
>
> ああっ!浅山さん、upper() していたのですね。
> これがたぶんみんなが一番知りたかった情報です。
>
> 私のほうでも試してみたところ、どうも charset の設定にかかわらず
> upper されてしまうような挙動に見えます。不具合な予感。
> 以下皆さんにも判断していただきたく、やったことを書きます。
>
> --テーブルを作成し、データを3件INSERT。
> mysql> create table t (a varchar(16)) engine=myisam default charset=cp932;
> mysql> insert into t values ("ビタ");
> mysql> insert into t values ("ABC");
> mysql> insert into t values ("abc");
>
> --UPPER() の挙動を確認(参考)
> mysql> select * from t WHERE upper(a)="ABC";
> +------+
> | a |
> +------+
> | ABC |
> | abc |
> +------+
> 2 rows in set (0.00 sec)
>
> --問題の日本語文字でUPPER()の挙動を確認
> mysql> select * from t WHERE upper(a)="ビタ";
> Empty set (0.01 sec)
>
> mysql> select * from t WHERE upper(a)="コタ";
> +------+
> | a |
> +------+
> | ビタ |
> +------+
> 1 row in set (0.00 sec)
>
>
> ===============
> --UPPER()関数によって CP932の2バイト目がUPPERされてしまっていることの確認(不具合と思います)
>
> mysql> SELECT a, HEX(a), HEX(UPPER(a)) FROM t;
> +------+----------+---------------+
> | a | HEX(a) | HEX(UPPER(a)) |
> +------+----------+---------------+
> | ビタ | 8372835E | 8352835E |
> | ABC | 414243 | 414243 |
> | abc | 616263 | 414243 |
> +------+----------+---------------+
> 3 rows in set (0.00 sec)
>
>
> ===============
> --環境とか
> mysql> SHOW CREATE TABLE t\G
> *************************** 1. row ***************************
> Table: t
> Create Table: CREATE TABLE `t` (
> `a` varchar(16) default NULL
> ) ENGINE=MyISAM DEFAULT CHARSET=cp932
> 1 row in set (0.00 sec)
>
> mysql> status
> --------------
> :
> Server version: 5.0.45 Source distribution
> :
> Server characterset: cp932
> Db characterset: cp932
> Client characterset: cp932
> Conn. characterset: cp932
> --------------
>
> mysql> show create database test;
> +----------+----------------------------------------------------------------+
> | Database | Create Database |
> +----------+----------------------------------------------------------------+
> | test | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET cp932 */ |
> +----------+----------------------------------------------------------------+
> 1 row in set (0.00 sec)
>
> Thank you
>
> On Fri, 17 Apr 2009 20:38:31 +0900
> ALCYONE@xxxxx (浅山雄三) wrote:
> > 奥野様
> >
> > 浅山です。いつもお世話になります。
> >
> >
> > >その現象はテーブルの文字コードが違うときの現象に似てるんですが、
> > >もう一度テーブルの文字コードを確認して頂けませんか?
> > >
> > >mysql> SHOW CREATE TABLE テーブル名\G
> >
> > | Aテーブル | CREATE TABLE `Aテーブル` (
> > `AA_num` varchar(16) NOT NULL,
> > `BB_num` varchar(16) DEFAULT NULL,
> > `CC_num` varchar(16) DEFAULT NULL,
> > `DD_sb` text,
> > `EE_mei` text,
> > (以下、同様の行が205行)
> > `biko3` text,
> > `update_dattim` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON
> > UPDATE CURRENT_TIMESTAMP,
> > `FF_flg` varchar(1) DEFAULT NULL,
> > `GG_num` varchar(16) DEFAULT NULL,
> > `HH_num` varchar(16) DEFAULT NULL,
> > `II_url` varchar(500) DEFAULT NULL,
> > `biko4` text,
> > `biko5` text,
> > PRIMARY KEY (`AA_num`),
> > UNIQUE KEY `Aテーブル_uk1` (`JJ_num`),
> > KEY `Aテーブル_KK_num_idx1` (`LL_num`),
> > KEY `MM_flg_idx` (`LL_flg`)
> > ) ENGINE=MyISAM DEFAULT CHARSET=cp932 |
> >
> >
> > | Bテーブル | CREATE TABLE `Bテーブル` (
> > `AA_num` varchar(16) NOT NULL DEFAULT '',
> > `data` longtext,
> > `ngram` longtext,
> > PRIMARY KEY (`AA_num`),
> > FULLTEXT KEY `ngram` (`ngram`)
> > ) ENGINE=MyISAM DEFAULT CHARSET=cp932 |
> >
> >
> > >あと、問題になってるSELECT文も見せて頂けますでしょうか?
> >
> > select SQL_SMALL_RESULT AA_NUM, BB_NUM, CC_KJ, DD_EN, EE_EN,
> > FF_KJ1,length(trim(BB_NUM)) BB_NUM_LEN from Aテーブル DT, Bテーブル
> > TP where ((upper(DD_EN) like '%ビタミン%' or upper(GG_EN) like '%ビ
> > タミン%' or upper(CC_KJ) like '%ビタミン%') and (upper(DD_EN) like
> > '%サプリメント%' or upper(GG_EN) like '%サプリメント%' or upper
> > (CC_KJ) like '%サプリメント%')) and (upper(substr(HH_CD1,1,1)) =
> > 'B' or upper(substr(II_CD2,1,1)) = 'B' or upper(substr(JJ_CD3,1,1))
> > = 'B') and AA_NUM = TP.KANRI_NUM and (MATCH(NGRAM) AGAINST('+栄養
> > *' IN BOOLEAN MODE)) order by CC_KJ
> >
> >
> > ※ Aテーブルは[mysql 14797]のAテーブル
> > Bテーブルは[mysql 14797]のBテーブル
> > フィールド名の一部を実際とはかえています。
> >
> >
> > 2009年4月17日 20:38:27 (^o^)浅山雄三
>


投稿者 xml-rpc : 2009年4月17日 21:12
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/84310
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。