从数据库读取NVARCHAR后,TClientDataset Widestring字段的大小翻倍

时间:2012-11-14 12:55:03

标签: sql-server delphi

我正在将我们的一个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上调用.Open,以便通过链接组件获取数据 - &gt; TDatasetProvider-&gt; TSQLDataset(.CommandText =一个简单的select * from table) - &gt; TSQLConnection 。当我检查监视列表中字段的属性时,Size仍然是10,Datasize仍然是22.但是保存到XML文件后,该字段被定义为

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

..宽度增加了一倍?

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

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

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

2 个答案:

答案 0 :(得分:0)

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

大小加倍可能是两个隐式“转换”的结果:第一个 - 服务器提供存储在ansi-string字段中的NVarchar数据(每个字节变成一个单独的字符),第二个 - 存储到clientdataset的Widestring类型字段,每个字符变为2个字节(大小为双精度)。

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

答案 1 :(得分:-1)

听起来因为列数据类型被更改,它为您创建了意外问题。我的建议是 1.备份桌子,多种方式做到这一点,比喻说你的毒药 2.删除表格, 3.重新创建表格, 4.将旧表中的数据导入新创建的表。看看是否有帮助。

当列数据类型发生更改时,Sql表不喜欢它,并且这样做可能会产生意外问题。所以尝试一下,最糟糕的情况是,你浪费了大约十分钟的时间来尝试一个可能的解决方案。