3

我正在开发一个在 Delphi 2010 中构建的应用程序,该应用程序使用 UIB 连接到 Firebird 2.5 数据库。该应用程序已经使用默认字符集运行了很长时间,即没有人对字符集有任何特别的考虑,它一直在工作。目前我正在尝试使其与 UTF-8 数据一起正常工作。

在这样做时,我遇到了 TUIBQuery 和参数化查询的问题。当使用Database.Charset=csUTF8和设置 CHAR(n) 字段的参数值并在执行查询之前检索它时,该值将被截断。

不幸的是,我的一些代码在许多地方都像这样写入和读取参数,因此死得很丑。

为了隔离和演示问题,我创建了一个简单的新数据库,其中DEFAULT CHARACTER SET UTF-8包含如下表:

  CREATE TABLE TEST (
    CHARFIELD CHAR(20),
    VARCHARFIELD VARCHAR(20)
  );

我将应用程序设置为使用 TUIBDatabase 和 TUIBTransaction 连接到数据库。然后我创建了一个 TUIBQuery 实例,将 SQL 设置为该表的参数化 INSERT 语句,并设置参数:

  Query := TUIBQuery.Create(NIL);
  Query.Transaction := Transaction;
  Query.SQL.Text := 'INSERT INTO TEST (CHARFIELD, VARCHARFIELD) VALUES (:CHARFIELD, :VARCHARFIELD)';
  Query.Prepare(True);

  s:= 'ABC';

  Query.Params.ByNameAsString['CHARFIELD'] := s;
  Query.Params.ByNameAsString['VARCHARFIELD'] := s;

当我现在像这样读取参数值时:

  s := Query.Params.ByNameAsString['CHARFIELD'];
  s := Query.Params.ByNameAsString['VARCHARFIELD'];

结果对Database.Charset=csNone. 但是,当我改为指定DataBase.Charset=csUTF8CHARFIELD 的值时,将截断为'A'而不是'ABC'. VARCHARFIELD 的值很好。该行为与实际数据无关,我不必实际使用非 ASCII 字符来激发它,如示例所示。

在查询上调用 ExecSQL() 可以正常工作,并且在两种情况下都按预期插入数据。

我已将源代码作为UIB_UTF8_Test.zip上传到我的简单测试程序中。

这里有人知道我可能做错了什么以及如何做对吗?

4

0 回答 0