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