Подтвердить что ты не робот

TClientDataset Поле Widestring удваивается после чтения NVARCHAR из базы данных

Я конвертирую один из наших проектов Delphi 7 в Delphi X3, потому что мы хотим поддерживать Unicode. Мы используем MS SQL Server 2008/R2 в качестве нашего сервера базы данных. После изменения некоторых полей базы данных от VARCHAR до NVARCHAR (и полей в сопровождающих ClientDatasets на ftWideString) произошли случайные сбои. Во время отладки я заметил неожиданное поведение TClientDataset/DbExpress:

Для базы данных NVARCHAR (10) я вручную создаю TWideStringField в наборе clientdataset и устанавливаю свойство 'Size' равным 10. Свойство DataSize этого поля говорит мне, что требуется 22 байта, что ожидается, так как кодирование TWideStringField UTF-16, поэтому ему нужно два байта на символ и некоторое пространство для хранения длины. Теперь, когда я вызываю "CreateDataset" в ClientDataset и записываю набор данных в XML (используя .SaveToFile), в XML файле поле определяется как

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

который выглядит нормально для меня.

Теперь вместо вызова .CreateDataset я вызываю. Откройте в TClientDataset, чтобы он получал свои данные через связанные компоненты → TDatasetProvider- > TSQLDataset (.CommandText = простой выбор * из таблицы) → TSQLConnection. Когда я проверяю свойства поля в своем списке просмотра, размер по-прежнему равен 10, Datasize все равно 22. После сохранения в файл XML это поле определяется как

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

.. ширина удвоилась?

Наконец, если я вызову. Открыть в TClientDataset, не создавая заранее никаких полей, размер поля будет 20 (неверно!) и Datasize 42. После сохранения в XML, поле по-прежнему определяется как

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

Кто-нибудь знает, что здесь не так?

4b9b3361

Ответ 1

Проверьте тип поля и его размер на компоненте SQLCommand (который находится перед DatasetProvider).

Увеличение размера может быть результатом двух неявных "преобразований": first-server предоставляет данные NVarchar, которые хранятся в поле ansi-string (и каждый байт становится отдельным символом), во-вторых - он хранится в поле clientdataset типа Widestring и каждый символ становятся 2 байтами (размер удваивается).

Обратите внимание, что в предыдущих версиях несоответствия размера поля строки Delphi между полем ClientDataset и соответствующим полем Query/Command не возникало исключение, но, начиная с одного из XE *, он выдавал результаты в AV. Поэтому при миграции вы должны тщательно проверить размер полей строки.

Ответ 2

Похоже, что из-за изменения типа столбца он создавал неожиданные проблемы для вас. Мое предложение состоит в том, чтобы 1. резервное копирование таблицы, несколько способов сделать это, выбрать свой яд образно говоря 2. Удалите таблицу, 3. воссоздать таблицу, 4. импортируйте данные из старой таблицы в новую созданную таблицу. Посмотрите, поможет ли это.

Таблицы Sql НЕ нравится, когда типы данных столбцов меняются, и из-за этого могут возникать неожиданные проблемы. Поэтому попробуйте, и в худшем случае, вы потратили впустую, может быть, десять минут вашего времени, пытаясь найти возможное решение.