14

我正在将我们的一个 Delphi 7 项目转换为 Delphi X3,因为我们想要支持 Unicode。我们使用 MS SQL Server 2008/R2 作为我们的数据库服务器。在将一些数据库字段从 VARCHAR 更改为 NVARCHAR(并将随附的 ClientDatasets 中的字段更改为 ftWideString)后,随机崩溃开始发生。在调试时,我注意到 TClientDataset/DbExpress 的一些意外行为:

对于 NVARCHAR(10) 数据库列,我在客户端数据集中手动创建一个 TWideStringField,并将“Size”属性设置为 10。该字段的“DataSize”属性告诉我需要 22 个字节,这是预期的,因为 TWideStringField 的编码是 UTF-16 ,所以它需要每个字符两个字节和一些空间来存储长度。现在,当我在 ClientDataset 上调用“CreateDataset”并将数据集写入 XML(使用 .SaveToFile)时,在 XML 文件中,该字段定义为

<FIELD WIDTH="20" fieldtype="string.uni" attrname="TEST"/>

这对我来说看起来不错。

现在,不是调用 .CreateDataset,而是调用 TClientDataset 上的 .Open,以便它通过链接的组件 ->TDatasetProvider->TSQLDataset(.CommandText = 从表中选择 *)->TSQLConnection 获取数据。当我检查监视列表中字段的属性时,Size 仍然是 10,Datasize 仍然是 22。但是,在保存到 XML 文件后,该字段被定义为

<FIELD WIDTH="40" fieldtype="string.uni" attrname="TEST"/>

..宽度增加了一倍?

最后,如果我在 TClientDataset 上调用 .Open 而不事先创建任何字段定义,则字段的大小随后将为20(不正确!)和数据大小 42。保存到 XML 后,该字段仍定义为

<FIELD WIDTH="40" fieldtype="string.uni" attrname="TEST"/>

有谁知道这里出了什么问题?

4

2 回答 2

0

在 SQLCommand 组件(在 DatasetProvider 之前)检查字段类型及其大小。

大小加倍可能是两个隐式“转换”的结果:首先 - 服务器提供 NVarchar 数据,该数据存储在 ansi-string 字段中(并且每个字节都成为一个单独的字符),其次 - 它存储在 clientdataset 类型为 Widestring 的字段中,每个字符变为 2 个字节(大小加倍)。

请注意,在先前版本的 Delphi 中,ClientDataset 的字段与相应的查询/命令字段之间的字符串字段大小不匹配不会导致异常,但从 XE* 之一开始,它通常会导致 AV。因此,您必须在迁移期间仔细检查字符串字段大小。

于 2016-02-13T12:44:20.850 回答
-1

听起来因为列数据类型被更改,它给你带来了意想不到的问题。我的建议是 1. 备份表,有多种方法,形象地说是挑毒 2. 删除表, 3. 重新创建表, 4. 将旧表中的数据导入到新创建的表中。看看是否有帮助。

当列数据类型发生变化时,SQL 表不喜欢它,这样做可能会出现意想不到的问题。所以尝试一下,在最坏的情况下,你可能浪费了十分钟的时间来尝试一个可能的解决方案。

于 2015-02-11T15:55:37.367 回答