sql-server - 从数据库读取 NVARCHAR 后,TClientDataset Widestring 字段的大小加倍

标签 sql-server delphi

我正在将 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 = 简单的 select * from table)->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"/>

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

最佳答案

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

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

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

关于sql-server - 从数据库读取 NVARCHAR 后,TClientDataset Widestring 字段的大小加倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13379228/

相关文章:

sql-server - 无法调试 t-sql 语句 - 无法连接到计算机 '.'

sql - 将 SQL 格式化为一行

.net - SQL Server 是否缓存 LINQ to SQL 查询?

delphi - 简单的 Delphi DBcharting

virustotal api 的 Json 解析结果

java - Gradle添加SQLServer依赖后,jar找不到Main类

sql-server - 选择声明以显示丢失的记录(简单问题)

delphi - 在delphi : interrupt encoding process中使用ffmpeg

delphi - 我可以设置什么文件的创建/上次修改/上次访问?

windows - 如何从Delphi代码的IShellItem2.GetProperty输出中获取FindData结构?