提问人:Co de Klopper 提问时间:11/14/2012 更新时间:2/13/2016 访问量:1850
TClientDataset Widestring 字段在从数据库中读取 NVARCHAR 后大小翻倍
TClientDataset Widestring field doubles in size after reading NVARCHAR from database
问:
我正在将我们的一个 Delphi 7 项目转换为 Delphi X3,因为我们希望支持 Unicode。我们使用 MS SQL Server 2008/R2 作为我们的数据库服务器。将某些数据库字段从 VARCHAR 更改为 NVARCHAR 后(将随附的 ClientDatasets 中的字段更改为 ftWideString),开始发生随机崩溃。在调试时,我注意到 TClientDataset/DbExpress 出现了一些意外行为:
对于 NVARCHAR(10) 数据库列,我在 clientdataset 中手动创建一个 TWideStringField,并将“Size”属性设置为 10。字段的“DataSize”属性告诉我需要 22 个字节,这是预期的,因为 TWideStringField 的编码是 UTF-16,因此每个字符需要两个字节和一些空间来存储长度。现在,当我在 ClientDataset 上调用“CreateDataset”并将数据集写入 XML 时(使用 .SaveToFile),在 XML 文件中,该字段定义为
<FIELD WIDTH="20" fieldtype="string.uni" attrname="TEST"/>
这在我看来还不错。
现在,与其调用.我调用 CreateDataset。在 TClientDataset 上打开,以便它通过链接的组件 ->TDatasetProvider->TSQLDataset (.CommandText = 从表中选择的简单 *)->TSQLConnection.当我检查监视列表中字段的属性时,Size 仍为 10,Datasize 仍为 22。但是,保存到 XML 文件后,该字段定义为
<FIELD WIDTH="40" fieldtype="string.uni" attrname="TEST"/>
..宽度翻了一番?
最后,如果我打电话给.在 TClientDataset 上打开,完全没有提前创建任何字段定义,字段的大小随后将为 20(不正确!),数据大小为 42。保存到 XML 后,该字段仍定义为
<FIELD WIDTH="40" fieldtype="string.uni" attrname="TEST"/>
有谁知道这里出了什么问题?
答:
听起来由于列数据类型被更改,它给您带来了意想不到的问题。我的建议是 1.备份表格,多种方法可以做到这一点,比喻说你的毒药 2. 删除表格, 3. 重新创建表, 4. 将数据从旧表导入到新创建的表中。看看是否有帮助。
当列数据类型发生更改时,Sql 表不喜欢它,这样做可能会出现意想不到的问题。所以试试吧,最坏的情况是,你浪费了十分钟的时间去尝试一个可能的解决方案。
在 SQLCommand 组件(位于 DatasetProvider 之前)检查字段类型及其大小。
大小加倍可能是两个隐式“转换”的结果:第一个 - 服务器提供 NVarchar 数据,该数据存储在 ansi-string 字段中(每个字节都变成一个单独的字符),第二个 - 它存储在 clientdataset 的 Widestring 类型的字段中,每个字符变为 2 个字节(大小加倍)。
请注意,在早期版本的 Delphi 中,ClientDataset 的字段和相应的 Query/Command 字段之间的字符串字段大小不匹配不会导致异常,但从 XE* 的其中一个开始,它会导致 AV。因此,您必须在迁移过程中仔细检查字符串字段大小。
评论