Character encoding 停止Firebird基于Windows字符集修改字符串

Character encoding 停止Firebird基于Windows字符集修改字符串,character-encoding,firebird,firebird1.5,uib,Character Encoding,Firebird,Firebird1.5,Uib,我有一个使用1.5.5 Firebird嵌入式引擎的应用程序(用Delphi编写)。我之所以使用这个引擎,是因为应用程序与当前部署的Firebird数据库一起工作,而较新的嵌入式引擎无法正确打开数据库文件(ODS 10.1)。数据库中的所有字符串都定义为VARCHAR(N),其中N不同。该应用程序以前是ANSI应用程序,因此数据包含ISO-latin-1字符。现在该应用程序升级为unicode应用程序。为了在现有数据库(大约10k个实例)中存储Unicode字符,我编写了一个UTF8-BOM(如

我有一个使用1.5.5 Firebird嵌入式引擎的应用程序(用Delphi编写)。我之所以使用这个引擎,是因为应用程序与当前部署的Firebird数据库一起工作,而较新的嵌入式引擎无法正确打开数据库文件(ODS 10.1)。数据库中的所有字符串都定义为VARCHAR(N),其中N不同。该应用程序以前是ANSI应用程序,因此数据包含ISO-latin-1字符。现在该应用程序升级为unicode应用程序。为了在现有数据库(大约10k个实例)中存储Unicode字符,我编写了一个UTF8-BOM(如果您可以这样称呼它),然后字符串的其余部分被认为是UTF8,并由数据库层进行解码。这样,我们可以使用所有现有的数据库,并且仍然使用所有Unicode字符

这适用于西欧的所有机器。但是,当应用程序在罗马尼亚运行时(带有罗马尼亚语言设置的Windows PC):数据库引擎会改变字符。例如:UTF8字符串以字符八位字节EF(ï)开头。数据库引擎将其作为八位字节69(i)返回

如何为现有数据库解决此问题

注意:我试图在打开数据库时指定一个字符集八位字节(使用UIB库),但由于字符集未知,因此失败了

发现问题出在UIB(本例中使用的数据库层)中。UIB处理csNONE的方式是,如果您给它一个字节字符串(数据类型AnsiString),它将通过简单地将字节扩展为单词并进一步使用当前的线程代码页将其减少,从而转换为UnicodeString。因为罗马尼亚没有使用iso-latin-1作为代码页。。。那里的数据被破坏了

目前,我在UIBLib中更改了以下例程(例如,当给定ansistring且字符集为none且请求ansistring参数->根本不进行转换时):


现在,我需要检查库的这种行为是否正确,并给维护人员一个补丁。

您现在使用的是什么连接字符集,默认字符集和/或特定列字符集是什么?另外:字符集
八位字节
不存在,它是
八位字节
,但我不确定是否可以将其用作连接字符集连接时使用的字符集在UIB中的枚举中指定,当前为csNONE。指定csOCTETS时,csISO8859_1产生未知字符集未定义错误。很抱歉,使用了名称OCTET(将更改它)而不是OCTET。Firebird embedded是否还包括
fbintl.conf
fbintl.dll
intl
文件夹,并且是否安装了这些字符集(如果未在
doc\README-intl.txt
上读取)。还请注意,如果使用characterset NONE,服务器将按原样发送数据并使用本地字符集进行转换,如果您返回0x69,则它将按原样存储,或者您的本地字符集转换将执行此操作。
  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;