Как правильно получить доступ к значению параметра VARCHAR(MAX) набора данных FireDAC при получении ошибки "данные слишком велики для переменной"?

Наше приложение обновляет данные и обращается к ним с помощью SQL Server 2014.

У меня есть таблица, в которой последний столбец ("Содержание") создается как VARCHAR(MAX),

Мы используем Delphi XE8 и используем FireDAC TFDQuery компонент для обновления этого столбца.

.....
FDquery.ParamByName('Contents').AsString:=Contents;
FDquery.ExecSQL;

При запуске этого обновления я получаю следующую ошибку:

Возникла исключительная ситуация с сообщением [FireDAC][Phys][ODBC]-345. Данные слишком велики для переменной [СОДЕРЖАНИЕ]. Max len = [8002], фактический len = [13829] Подсказка: установите большее значение TFDParam.Size.

"Содержимое" может быть строкой различной длины.

Просматривая Интернет, единственное достаточно простое решение, которое я нашел, - это изменить запрос следующим образом:

 FDquery.ParamByName('Contents').AsWideMemo:=Contents;
 FDquery.ExecSQL;     

Это приемлемо, или я должен обращаться с этим по-другому?

В "Содержании" нет ничего особенного, как я уже говорил, это просто длинная строка.

1 ответ

Допустимо ли обращаться к значению параметра поля типа VARCHAR(MAX) по свойству AsWideMemo?

Не особенно. Для параметра поля VARCHAR(MAX) используйте доступ AsMemo. Это потому, что вы можете отправлять в СУБД значения Unicode в поле, отличное от Unicode. Из ссылки:

Значение параметра в кодировке Unicode преобразуется в набор символов Unicode, который поддерживается СУБД, и отправляется в СУБД. Это не зависит от набора символов клиента или от версии Delphi.

Если ваше поле будет NVARCHAR(MAX), использование AsWideMemo будет правильным выбором для значения параметра.


Почему я получаю сообщение об ошибке "данные слишком велики для переменной", когда свойство AsString присвоило строку длиной более 8 тысяч символов?

Некоторый фон, почему это происходит. Получая доступ к определенному значению параметра через свойство As , движок также устанавливает параметр DataType, если вы явно не делали этого раньше. В данном конкретном случае вы намекали движку, что он подходит для вас, если он устанавливает тип данных параметра на ftWideString или ftString, просто получая доступ к значению параметра через свойство AsString.

А благодаря отображению типов данных такой параметр обрабатывается как тип данных VARCHAR[n] или NVARCHAR[n], включая его пределы (следовательно, здесь вы получили ошибку ограничения длины строки).

Аналогично, только более конкретная подсказка типа данных используется, когда вы обращаетесь к значению параметра через свойство AsMemo, по умолчанию это тип данных ftMemo, который отображается на VARCHAR(MAX). И, как вы можете предсказать, доступ AsWideMemo по умолчанию имеет значение ftWideMemo, которое соответствует типу данных NVARCHAR(MAX). Если вы не хотите явно устанавливать типы данных параметров, но используете этот совет, обратитесь к руководству, чтобы увидеть, как каждое используемое свойство доступа устанавливает тип данных параметров по умолчанию.

Другие вопросы по тегам