При интеграции 1С с внешними базами данных MS SQL Server часто возникает задача получения больших объемов текстовых данных, таких как XML-выгрузки, логи или JSON-пакеты. Если хранимая процедура возвращает такие данные через выходной (OUTPUT) параметр типа varchar(max) или nvarchar(max), разработчики сталкиваются с проблемой: данные либо обрезаются на отметке 8000 символов, либо система выдает ошибку при попытке указать неопределенную длину параметра. В этой статье мы подробно разберем, как правильно настроить объект ADODB.Command, чтобы успешно считывать строки любой длины.
Основная сложность заключается в правильном подборе констант для метода CreateParameter. В стандартной документации ADO для обычных строк используется тип adVarWChar (значение 130), но он имеет жесткие ограничения. Для работы с типами данных MAX (BLOB-объектами) необходимо использовать специализированные типы.
Рассмотрим по шагам процесс создания и настройки параметра:
130 (adWChar), используем 203 (adLongVarWChar) для Unicode строк (nvarchar) или 201 (adLongVarChar) для обычных строк (varchar).2 (adParamOutput).-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;
Иногда использование выходных параметров (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();
Проанализируем ситуацию, когда данные все равно приходят пустыми или обрезанными. Существует несколько тонкостей, которые могут повлиять на результат:
SQLOLEDB часто некорректно работает с типами MAX. Рекомендуется использовать SQLNCLI11 (SQL Server Native Client) или современный MSOLEDBSQL (Microsoft OLE DB Driver for SQL Server).Recordset не будет закрыт. Всегда вызывайте Recordset.Close() перед обращением к Command.Parameters().Value.0 вместо 2147483647. Если один вариант выдает ошибку, попробуйте другой.Посмотрим на итоговую рекомендацию: Для максимально стабильной работы при передаче XML-данных большого объема (свыше 10-20 Мб) из SQL в 1С, лучше всего использовать Метод 2 (Recordset) с драйвером MSOLEDBSQL. Это избавит вас от ручного управления размерами буфера и гарантирует целостность данных.