2

1.5.5 Firebird組み込みエンジンを使用するアプリケーション(Delphiで記述)があります。アプリケーションは現在デプロイされているFirebirdデータベースで動作し、新しい組み込みエンジンではデータベースファイルが正しく開かないため、このエンジンを使用しています(ODS10.1)。データベース内のすべての文字列は、Nが変化するVARCHAR(N)として定義されます。アプリケーションは以前はANSIアプリケーションであったため、データにはISO-latin-1文字が含まれています。これで、アプリケーションがUnicodeアプリにアップグレードされました。Unicode文字を既存のデータベース(約1万インスタンス)に格納するために、UTF8-BOM(呼び出し可能な場合)を記述します。その後、文字列の残りの部分はUTF8と見なされ、データベースレイヤーによってデコードされます。このようにして、既存のすべてのデータベースを使用しながら、すべてのUnicode文字を使用できます。

これは、西ヨーロッパのすべてのマシンでうまく機能します。ただし、アプリケーションがルーマニア(ルーマニア語設定のWindows PC)で実行されている場合、データベースエンジンが文字を変更します。例:UTF8文字ストリングは、文字オクテットEF(ï)で始まります。データベースエンジンはそれをオクテット69(i)として返します。

この問題は、既存のデータベースでどのように解決できますか?

注意:データベースを開くときに(UIBライブラリを使用して)文字セットOCTETSを指定しようとしましたが、文字セットが不明であるため失敗します。

問題がUIB(この場合に使用されるデータベースレイヤー)内にあることがわかりました。UIBは、バイト単位の文字列(データ型AnsiString)を指定すると、バイトを単語に拡張するだけでUnicodeStringに変換され、さらに現在のスレッドのコードページで縮小されるようにcsNONEを処理します。ルーマニアはコードページとしてiso-latin-1を使用していなかったため、データが破損しています。

今のところ、UIBLibで次のルーチンを変更しました(たとえば、ansistringが指定され、charsetがnoneで、ansistringパラメーターが要求された場合->変換をまったく行わない場合)。

  procedure TSQLDA.EncodeStringA(Code: Smallint; Index: Word; const str: AnsiString);
  begin
  {$IFDEF UNICODE}
    if FCharacterSet = csNONE then begin // new
      EncodeStringB( Code, Index, str ); // new
    end else begin                       // new
      EncodeStringB(Code, Index, MBUEncode(UniCodeString(str), CharacterSetCP[FCharacterSet]));
    end;                                 // new
  {$ELSE}
    EncodeStringB(Code, Index, str);
  {$ENDIF}
  end;

次に、この動作がライブラリに対して正しいかどうかを確認し、メンテナにパッチを適用する必要があります。

4

0 に答える 0