Как решить проблему с подключением к Oracle x64 через ADODB в 1С:Предприятие 8.3?

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

При переходе на 64-битную версию платформы 1С:Предприятие и 64-битный клиент Oracle разработчики часто сталкиваются с ошибками при попытке использовать привычные COM-объекты ADODB.Connection и ADODB.Command. Если стандартное выполнение запроса через объект RecordSet проходит успешно, то связывание команды с соединением через свойство ActiveConnection или создание параметров может вызывать ошибку COM:

Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another (0x800A0BB9).

Разберем причины возникновения этой ошибки в 64-разрядной среде и рассмотрим надежные способы решения задачи передачи параметров и вызова процедур СУБД Oracle.

Причины возникновения ошибки в среде x64

Проанализируем технические особенности работы с OLE DB в 64-битной архитектуре:

  1. Необъявленные константы перечислений ADO: В языке 1С нет встроенных констант ADO (таких как adInteger, adParamInput, adCmdStoredProc). В 32-битном окружении или при определенных типах драйверов некоторые значения могли интерпретироваться по умолчанию, однако в 64-битном клиенте передача пустых значений (Неопределено) немедленно приводит к исключению несоответствия типов.
  2. Особенности маршалинга COM-интерфейсов в 64-битных процессах: Свойство ActiveConnection объекта ADODB.Command принимает как ссылку на объект Connection, так и строку подключения. При позднем связывании (IDispatch) в 64-битном драйвере OraOLEDB.Oracle передача ссылки на другой COM-объект может вызывать сбой сопоставления типов.
  3. Различия между драйверами MSDAORA и OraOLEDB: Устаревший Microsoft OLE DB Provider for Oracle (MSDAORA) существует исключительно в 32-битной версии. При переходе на 64-битный провайдер Oracle (OraOLEDB.Oracle) меняются требования к синтаксису вызова процедур и передаче параметров.

Способ 1. Использование встроенного механизма «Внешние источники данных»

Рассмотрим основной и наиболее надежный способ интеграции 1С с СУБД Oracle, не зависящий от COM-библиотек Windows. Платформа 1С:Предприятие 8.3 позволяет подключить внешнюю базу данных напрямую через механизм внешних источников данных (ВИД).

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

  1. Установим 64-разрядный ODBC-драйвер Oracle (Oracle Database Client x64) на сервере 1С.
  2. В дереве метаданных конфигурации 1С добавим новый объект Внешний источник данных.
  3. В свойствах источника укажем строку подключения ODBC. Посмотрим на пример строки подключения:

СтрокаПодключения = "DRIVER={Oracle in OraClient12home1};UID=имя_пользователя;PWD=пароль;DBQ=TEST";
ПараметрыПодключения = Новый ПараметрыПодключенияВнешнегоИсточникаДанных;
ПараметрыПодключения.СтрокаСоединения = СтрокаПодключения;
ВнешниеИсточникиДанных.ВнешняяБДOracle.УстановитьПараметрыПодключения(ПараметрыПодключения);
ВнешниеИсточникиДанных.ВнешняяБДOracle.УстановитьСоединение();
  1. С помощью мастера добавления таблиц и процедур внешнего источника выберем нужные таблицы и хранимые процедуры Oracle.
  2. После импорта метаданных вызов процедур с параметрами и выполнение запросов выполняются стандартными средствами встроенного языка 1С:

// Вызов хранимой функции/процедуры внешнего источника
Результат = ВнешниеИсточникиДанных.ВнешняяБДOracle.ХранимыеПроцедуры.ИмяПроцедуры(ЗначениеПараметра1, ЗначениеПараметра2);

// Выполнение запроса с параметрами к таблице внешнего источника
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Таблица.Поле1,
    |   Таблица.Поле2
    |ИЗ
    |   ВнешнийИсточникДанных.ВнешняяБДOracle.Таблица.ТаблицаOracle КАК Таблица
    |ГДЕ
    |   Таблица.Идентификатор = &Идентификатор";
Запрос.УстановитьПараметр("Идентификатор", ИскомыйИД);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();

Способ 2. Корректная инициализация параметров и вызовов ADODB

Если архитектура проекта требует сохранить работу через COM-объект ADODB, необходимо строго соблюдать типы параметров и правила передачи соединения.

Посмотрим на пример правильной инициализации констант ADO и вызова параметризованного запроса:


// Объявляем числовые эквиваленты констант ADO
adInteger = 3;
adVarChar = 200;
adParamInput = 1;
adCmdText = 1;

СтрокаСоединения = "Provider=OraOLEDB.Oracle;Data Source=TEST;User Id=ххх;Password=хххх;";

objCon = Новый COMОбъект("ADODB.Connection");
objCon.ConnectionString = СтрокаСоединения;
objCon.Open();

objCmd = Новый COMОбъект("ADODB.Command");
// Если прямая передача objCon вызывает ошибку, передаем строку подключения
objCmd.ActiveConnection = objCon;
objCmd.CommandType = adCmdText;
objCmd.CommandText = "SELECT COUNT(1) FROM ss s WHERE s.id_promr = ?";

// Передаем точные числовые типы констант
ПараметрИД = objCmd.CreateParameter("id_prom", adInteger, adParamInput, , Число(ИскомыйИД));
objCmd.Parameters.Append(ПараметрИД);

RecordSet = objCmd.Execute();

Пока НЕ RecordSet.EOF Цикл
    // Обработка данных
    RecordSet.MoveNext();
КонецЦикла;

RecordSet.Close();
objCon.Close();

Способ 3. Вызов процедур через анонимные PL/SQL-блоки

При возникновении конфликтов с коллекцией Parameters объекта Command вызов процедур СУБД Oracle можно осуществить напрямую через метод Execute объекта Connection с помощью анонимного блока PL/SQL:


ТекстPLSQL = 
    "BEGIN
    |    имя_схемы.имя_процедуры(" + Формат(Число(ИскомыйИД), "ЧГ=0") + ");
    |END;";

objCon.Execute(ТекстPLSQL);

Этот способ позволяет гарантированно передавать вызовы процедур на сервер Oracle без использования промежуточного объекта ADODB.Command.

← На главную