日本語文字列でLIKE検索を行う場合などのトラブルの回避方法について説明します
日本語データの検索の問題点と対策
- 問題点
DBISAMのSQLエンジンが、日本語SJISのマルチバイト文字を正しく処理できない。
** 症状1)
「表」という文字の2バイト目には「\」と同じ文字コードが入っているため、SELECT FROM ....
WHERE ... LIKE "%\%" が、"表”を含むテキストにヒットしてしまう。** 症状2)
半角カナ、「棒」「ダ」など、一致しないものまでやたらにヒットする。文字列比較にWindowsAPIのCompareStringを呼んでいるのですが
ここで、NORM_IGNORENONSPACE(場所を取らない文字を区別しない)オプションが
セットされており、2バイト文字の1バイト目は無条件に捨てられるという問題が存在します。 - 対策
 
2-1) DBISAMLb.pas のfunction CompareMBCSCharを以下で置き換えます。
  procedure MBCSInc(LocaleID: Integer; var CurPtr: PChar);
  begin
     if (LocaleID <> LOCALE_ANSI_STD) then
        begin
        if (StrByteType(CurPtr,0)=mbLeadByte) then
           Inc(CurPtr);
        if (CurPtr^=#0) then
           Exit;
        end;
     Inc(CurPtr);
  end;
  function CompareMBCSChar(LocaleID: Word;
                         FirstChar: PChar; SecondChar: PChar): Integer;
   begin
     Result:=OSCompareCharNoAccent(LocaleID,FirstChar^,SecondChar^);
   if (LocaleID <> LOCALE_ANSI_STD) and (Result=CMP_EQUAL) then
   begin
      Result := Ord(FirstChar^) - Ord(SecondChar^); //K.Okada 2005/7/3 //*****
      if (Result = CMP_EQUAL) and (StrByteType(FirstChar,0)=mbLeadByte) then  //*****
         begin
           Inc(FirstChar);
           Inc(SecondChar);
           if (FirstChar^=#0) and (SecondChar^=#0) then
              Result:=CMP_EQUAL
           else if (FirstChar^=#0) and (SecondChar^ <> #0) then
              Result:=CMP_LESS
           else if (FirstChar^ <> #0) and (SecondChar^=#0) then
              Result:=CMP_GREATER
           else
              Result:=Ord(FirstChar^) - Ord(SecondChar^);                     //*****
          end;
     end;
   end;
注意
        上記の修正を生かすには、テーブルのLOCALEを日本語にする必要があります(デフォルトはANSI_STD)。DBSYSでもセットできますし、SQLのCREATE
        TABLE文、ALTER TABLE文にロケール1041を指定してもOKです。
例)
CREATE TABLE IF NOT EXISTS "new" ( "AAA" VARCHAR(10), PRIMARY KEY ("RecordID") COMPRESS NONE LOCALE CODE 1041 );
現在のDBISAMのソースには、米国ElevateSoftによって上記の修正が部分的に反映されていますが、中途半端なので、必ず上記のコードで置き換えてください。特にMBCSInc関数は一見すると似ていますが、よく見ると間違っています。
※日本語対応のための修正を弊社にて行い、時々メールで通知していたのですが、日本語のための修正が他のヨーロッパ言語に悪影響を及ぼす恐れがあり、また現在DBISAMの開発陣は、.NET・Unicodeに対応するVer.5の開発に入っていることもあるため、最新の日本語用修正分については弊社の手許に留めております。
