При интеграции 1С с внешними базами данных (такими как MySQL или MariaDB) через COM-объект ADODB разработчики нередко сталкиваются с крайне неприятной проблемой: внешнее соединение устанавливается успешно, запрос выполняется без видимых ошибок, однако при попытке обхода выборки (например, при проверке свойства EOF или вызове метода MoveNext) платформа 1С аварийно завершает работу с генерацией дампа памяти (Memory Access Violation). В этой статье мы подробно проанализируем причины этой проблемы и по шагам настроим стабильное подключение.
Самой распространенной причиной мгновенного падения платформы 1С при обращении к свойствам Recordset является несовпадение разрядности (битности) драйвера СУБД и исполняемого процесса 1С. Рассмотрим, как устроен этот механизм на практике.
Технология COM-соединения жестко привязана к разрядности процесса, который её вызывает:
&НаСервере), то драйвер ODBC на сервере обязательно должен быть 64-разрядным (x64).Если разрядность не совпадает (например, у вас установлена платформа 1С x86, а коннектор драйвера MySQL установлен x64), попытка вызвать свойства объекта COM-объекта, требующие прямой передачи структуры данных из системной памяти (такие как Eof), приводит к нарушению адресации. Платформа не может обработать некорректный указатель памяти и аварийно завершает свою работу.
Важный нюанс администрирования в Windows x64:
Для настройки источников данных ODBC используются две разные утилиты, чьи пути могут ввести в заблуждение:
%systemroot%\System32\odbcad32.exe отвечает за администрирование 64-разрядных драйверов.%systemroot%\SysWOW64\odbcad32.exe отвечает за настройку 32-разрядных драйверов.При настройке системных DSN обязательно используйте ту версию утилиты, которая соответствует разрядности вашего исполняемого процесса 1С.
По умолчанию COM-объект ADODB.RecordSet инициализирует однопроходный курсор, который оптимизирован для быстрого чтения, но крайне чувствителен к стабильности канала связи и специфике драйверов СУБД. Настройка параметров курсора вручную позволяет решить проблемы с закрытием объекта во время работы.
Разберем по шагам, какие свойства необходимо явно задавать перед открытием набора записей:
3 (adUseClient). В этом случае весь объем выборки сразу кэшируется в оперативной памяти клиента, минимизируя нагрузку на сеть во время обхода в цикле.3 (adOpenStatic) создает статическую копию данных. Это самый стабильный вариант для обхода выборки в 1С.1 (adLockReadOnly), чтобы не накладывать транзакционные блокировки на таблицы СУБД.Посмотрим на пример правильной инициализации и настройки объекта:
Соединение = Новый COMОбъект("ADODB.Connection");
// Настройка строки подключения...
Соединение.Open(Соединение_param);
НаборЗаписей = Новый COMОбъект("ADODB.RecordSet");
НаборЗаписей.CursorLocation = 3; // Клиентский курсор
НаборЗаписей.CursorType = 3; // Статический курсор
НаборЗаписей.LockType = 1; // Только чтение
НаборЗаписей.ActiveConnection = Соединение;
НаборЗаписей.Open("SELECT * FROM wp_wc_product_meta_lookup");
Пока НЕ НаборЗаписей.EOF Цикл
// Обработка полученной строки
ТекущееЗначение = НаборЗаписей.Fields("meta_key").Value;
НаборЗаписей.MoveNext();
КонецЦикла;
НаборЗаписей.Close();
Соединение.Close();
Еще один фактор, из-за которого падает платформа 1С при вызове MoveNext — это несовместимость типов данных Windows с типами данных внешней СУБД. При выполнении запроса вида SELECT * драйвер пытается транслировать все имеющиеся поля таблицы.
Если в таблице MySQL присутствуют сложные типы данных, такие как огромные бинарные поля BLOB, специфические типы GEOMETRY, новые структуры JSON или поля с неподдерживаемой кодировкой, COM-объект ADO не сможет корректно сопоставить их с типами платформы 1С. Результатом этого сопоставления становится критический сбой памяти.
Рекомендация: Всегда перечисляйте только нужные поля в запросе. Если поле имеет сложный или нестандартный тип, принудительно приводите его к строковому или числовому представлению прямо на стороне СУБД с помощью SQL-функций:
ТекстЗапроса = "SELECT product_id, CAST(meta_value AS CHAR) AS meta_value_string FROM wp_wc_product_meta_lookup";
НаборЗаписей.Open(ТекстЗапроса);
Обратите внимание на синтаксические конструкции языка 1С при работе с COM-объектами. Свойство EOF (признак окончания набора записей) является свойством объекта, а не методом. В коде 1С не следует использовать круглые скобки при обращении к нему.
Вместо ошибочного вызова:
Пока не НаборЗаписей.Eof() Цикл
Следует писать строго без скобок:
Пока НЕ НаборЗаписей.EOF Цикл
Использование скобок заставляет платформу искать метод EOF, которого нет у объекта, что в устаревших версиях драйверов также могло инициировать сбои обращения к памяти.
Драйверы MySQL ODBC очень чувствительны к флагам конфигурации, передаваемым в строке подключения через параметр Option (или OPTIONS). Эти флаги управляют низкоуровневой работой сокетов, кэшированием результатов и кодировками.
Например, добавление флага Option=3 (или других комбинаций, таких как Option=16384 для обработки больших пакетов данных) принудительно отключает кэширование результатов на стороне драйвера СУБД и активирует корректный возврат задействованных строк. Без правильных флагов драйвер может передавать некорректную информацию о размере буфера в ADO, провоцируя падение 1С.
Пример оптимизированной строки подключения с параметрами:
Соединение_param = "driver={MySQL ODBC 5.1 Driver}; server=" + СокрЛП(Сервер) +
"; uid=" + СокрЛП(Пользователь) +
"; pwd=" + СокрЛП(Пароль) +
"; database=" + СокрЛП(База) +
"; Option=3; STMT=SET CHARACTER SET utf8";
Поскольку технология COM/ADO считается устаревшей и сильно зависит от операционной системы Windows и разрядности процессов, мы рекомендуем рассмотреть более надежные архитектурные подходы интеграции 1С с СУБД MySQL:
HTTPСоединение. Данный подход полностью решает проблемы с установкой драйверов ODBC, разрядностью платформ и безопасностью портов СУБД.