Как получить строку неограниченной длины (varchar(max)) из SQL-процедуры через ADODB.Command в 1С

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними базами данных MS SQL Server часто возникает задача получения больших объемов текстовых данных, таких как XML-выгрузки, логи или JSON-пакеты. Если хранимая процедура возвращает такие данные через выходной (OUTPUT) параметр типа varchar(max) или nvarchar(max), разработчики сталкиваются с проблемой: данные либо обрезаются на отметке 8000 символов, либо система выдает ошибку при попытке указать неопределенную длину параметра. В этой статье мы подробно разберем, как правильно настроить объект ADODB.Command, чтобы успешно считывать строки любой длины.

Метод 1: Настройка выходного параметра ADO

Основная сложность заключается в правильном подборе констант для метода CreateParameter. В стандартной документации ADO для обычных строк используется тип adVarWChar (значение 130), но он имеет жесткие ограничения. Для работы с типами данных MAX (BLOB-объектами) необходимо использовать специализированные типы.

Рассмотрим по шагам процесс создания и настройки параметра:

  1. Выбор типа данных: Вместо стандартного 130 (adWChar), используем 203 (adLongVarWChar) для Unicode строк (nvarchar) или 201 (adLongVarChar) для обычных строк (varchar).
  2. Указание направления: Для получения значения используем константу 2 (adParamOutput).
  3. Определение размера: Поскольку 1С через COM-интерфейс не всегда корректно воспринимает значение -1, следует указывать максимально возможное значение для 32-битного целого числа — 2147483647.

Проанализируем пример кода для реализации этого метода:


// Создаем объекты ADO
Connection = Новый COMОбъект("ADODB.Connection");
Connection.Open(СтрокаПодключения);

Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "GetLargeMessage"; // Имя вашей процедуры
Command.CommandType = 4; // adCmdStoredProc

// Добавляем входной параметр
Command.Parameters.Append(Command.CreateParameter("@ID", 3, 1, 4, НужныйID));

// Добавляем выходной параметр для длинной строки
// 203 - adLongVarWChar (для nvarchar(max))
// 2 - adParamOutput
// 2147483647 - максимальный размер
Command.Parameters.Append(Command.CreateParameter("@msg", 203, 2, 2147483647));

Command.Execute();

// Получаем результат
РезультатСтрока = Command.Parameters("@msg").Value;

Метод 2: Использование Recordset для больших данных

Иногда использование выходных параметров (Output Parameters) может быть нестабильным из-за настроек конкретного OLE DB провайдера или ограничений сетевого протокола. В таких случаях мы рекомендуем изменить логику хранимой процедуры так, чтобы она возвращала строку не в параметре, а как результат обычного запроса SELECT.

Этот способ считается более надежным для передачи BLOB-данных, так как ADO обрабатывает результат как ISequentialStream, что минимизирует риски обрезания строки. Выясним, как это выглядит на практике.

В SQL-процедуре вместо:

SET @msg = (SELECT LargeText FROM MyTable WHERE ID = @N)

Используйте:

SELECT LargeText as Data FROM MyTable WHERE ID = @N

В коде 1С обработка будет выглядеть следующим образом:


Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "GetLargeMessageRecordset";
Command.CommandType = 4;

// Передаем только входной параметр
Command.Parameters.Append(Command.CreateParameter("@ID", 3, 1, 4, 10));

// Выполняем команду и получаем Recordset
Recordset = Command.Execute();

Если Не Recordset.EOF Тогда
    // Получаем значение через коллекцию Fields
    БольшаяСтрока = Recordset.Fields("Data").Value;
КонецЕсли;

Recordset.Close();

Важные нюансы и типичные ошибки

Проанализируем ситуацию, когда данные все равно приходят пустыми или обрезанными. Существует несколько тонкостей, которые могут повлиять на результат:

  1. Версия драйвера (Provider): Старый драйвер SQLOLEDB часто некорректно работает с типами MAX. Рекомендуется использовать SQLNCLI11 (SQL Server Native Client) или современный MSOLEDBSQL (Microsoft OLE DB Driver for SQL Server).
  2. Порядок чтения данных: В ADO существует специфика: если процедура возвращает и набор записей (Recordset), и выходные параметры, значения параметров могут быть недоступны, пока Recordset не будет закрыт. Всегда вызывайте Recordset.Close() перед обращением к Command.Parameters().Value.
  3. Тип adLongVarWChar: Если вы используете этот тип, некоторые драйверы могут потребовать указания размера 0 вместо 2147483647. Если один вариант выдает ошибку, попробуйте другой.

Посмотрим на итоговую рекомендацию: Для максимально стабильной работы при передаче XML-данных большого объема (свыше 10-20 Мб) из SQL в 1С, лучше всего использовать Метод 2 (Recordset) с драйвером MSOLEDBSQL. Это избавит вас от ручного управления размерами буфера и гарантирует целостность данных.

← На главную