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"/>
Кто-нибудь знает, что здесь не так?
Ответы
Ответ 1
Проверьте тип поля и его размер на компоненте SQLCommand (который находится перед DatasetProvider).
Увеличение размера может быть результатом двух неявных "преобразований": first-server предоставляет данные NVarchar, которые хранятся в поле ansi-string (и каждый байт становится отдельным символом), во-вторых - он хранится в поле clientdataset типа Widestring и каждый символ становятся 2 байтами (размер удваивается).
Обратите внимание, что в предыдущих версиях несоответствия размера поля строки Delphi между полем ClientDataset и соответствующим полем Query/Command не возникало исключение, но, начиная с одного из XE *, он выдавал результаты в AV. Поэтому при миграции вы должны тщательно проверить размер полей строки.
Ответ 2
Похоже, что из-за изменения типа столбца он создавал неожиданные проблемы для вас. Мое предложение состоит в том, чтобы
1. резервное копирование таблицы, несколько способов сделать это, выбрать свой яд образно говоря
2. Удалите таблицу,
3. воссоздать таблицу,
4. импортируйте данные из старой таблицы в новую созданную таблицу. Посмотрите, поможет ли это.
Таблицы Sql НЕ нравится, когда типы данных столбцов меняются, и из-за этого могут возникать неожиданные проблемы. Поэтому попробуйте, и в худшем случае, вы потратили впустую, может быть, десять минут вашего времени, пытаясь найти возможное решение.