日本語文字列でLIKE検索を行う場合などのトラブルの回避方法について説明します

日本語データの検索の問題点と対策

  1. 問題点

    DBISAMのSQLエンジンが、日本語SJISのマルチバイト文字を正しく処理できない。

    ** 症状1)
    「表」という文字の2バイト目には「\」と同じ文字コードが入っているため、SELECT FROM ....
    WHERE ... LIKE "%\%" が、"表”を含むテキストにヒットしてしまう。

    ** 症状2)
    半角カナ、「棒」「ダ」など、一致しないものまでやたらにヒットする。文字列比較にWindowsAPIのCompareStringを呼んでいるのですが
    ここで、NORM_IGNORENONSPACE(場所を取らない文字を区別しない)オプションが
    セットされており、2バイト文字の1バイト目は無条件に捨てられるという問題が存在します。

  2. 対策

 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の開発に入っていることもあるため、最新の日本語用修正分については弊社の手許に留めております。