Как настроить обмен данными между 1С 7.7 и СУБД Oracle через ADO

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Интеграция устаревших платформ, таких как 1С:Предприятие 7.7, с современными корпоративными базами данных (например, Oracle Database) — задача частая, но сопряженная с целым рядом технических нюансов. Основная сложность заключается в правильном конфигурировании драйверов подключения, обработке прав доступа в операционных системах Windows 7/10, а также в специфике вызова хранимых процедур и функций пакетов Oracle из кода 1С.

В этой статье мы подробно разберем, как организовать надежное соединение с сервером Oracle с помощью технологии ADO, как обойти типичные ошибки инициализации (включая популярную ошибку ORA-00604), а также научимся вызывать функции инициализации контекста сессии непосредственно из среды 1С 7.7.

Шаг 1. Выбор и настройка OLE DB провайдера

Для подключения к Oracle из 1С 7.7 обычно используют один из двух OLE DB провайдеров:

  1. MSDAORA (Microsoft OLE DB Provider for Oracle) — классический, но устаревший провайдер от Microsoft. Он поставляется вместе с Windows, однако официально не развивается и имеет проблемы с поддержкой некоторых современных типов данных и кодировок.
  2. OraOLEDB.Oracle (Oracle Provider for OLE DB) — "родной" провайдер от самой корпорации Oracle. Он работает быстрее, стабильнее и поставляется в составе пакетов Oracle Client или ODAC (Oracle Data Access Components).

Важное примечание: Платформа 1С 7.7 является исключительно 32-разрядным (x86) приложением. Это означает, что на компьютере, с которого выполняется подключение, обязательно должен быть установлен 32-битный клиент Oracle (Oracle Client x86), даже если сама операционная система Windows является 64-битной. 64-битные драйверы ADO платформа 1С 7.7 использовать не сможет.

Шаг 2. Настройка строки подключения (ConnectionString)

Рассмотрим два основных варианта формирования строки подключения к базе данных. Выбор зависит от того, используем ли мы локальный конфигурационный файл tnsnames.ora или хотим жестко прописать параметры сервера прямо в коде.

Вариант А. Использование файла tnsnames.ora

Для начала проанализируем структуру конфигурационного файла tnsnames.ora, который располагается по пути установки вашего Oracle-клиента (например, C:\oracle\product\11.2.0\client_1\network\admin\tnsnames.ora). Пропишем в него алиас нашей базы данных:


MOON =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 123.4.56.78)(PORT = 1111))
    )
    (CONNECT_DATA =
      (SID = PRD)
    )
  )

Теперь в 1С 7.7 мы можем подключиться, указав имя этого алиаса в параметре Data Source:


Соединение = СоздатьОбъект("ADODB.Connection");
Соединение.Provider = "OraOLEDB.Oracle"; // Или "MSDAORA.1"
Соединение.ConnectionString = "Data Source=MOON;User ID=XXXX;Password=xxxx;";
Попытка
    Соединение.Open();
    Сообщить("Соединение с Oracle успешно установлено!");
Исключение
    Предупреждение("Не удалось подключиться: " + ОписаниеОшибки());
КонецПопытки;

Вариант Б. Подключение без tnsnames.ora (Direct Connection / EZ Connect)

Если на клиентских компьютерах нет возможности централизованно настраивать файлы конфигурации, мы можем передать всю структуру параметров подключения (Description) непосредственно в строку соединения:


Соединение = СоздатьОбъект("ADODB.Connection");
Соединение.Provider = "OraOLEDB.Oracle";
ConnectionString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=123.4.56.78)(PORT=1111))(CONNECT_DATA=(SID=PRD)));User Id=XXXX;Password=xxxx;";
Соединение.ConnectionString = ConnectionString;
Попытка
    Соединение.Open();
    Сообщить("Прямое подключение установлено успешно!");
Исключение
    Предупреждение("Ошибка прямого подключения: " + ОписаниеОшибки());
КонецПопытки;

Шаг 3. Решение распространенных ошибок инициализации

При тестировании подключения в среде Windows 7 или Windows 10 администраторы и разработчики часто сталкиваются со следующей системной ошибкой:

Microsoft OLE DB Provider for Oracle: ORA-00604: error occurred at recursive SQL level %s

Выясним причины её возникновения и разберем способы решения этой проблемы.

Причина 1. Ограничение прав доступа к каталогу Oracle Client

Компоненты ADO запускаются операционной системой в контексте пользователя, под которым работает сессия 1С. Если у этого пользователя отсутствуют полные права на чтение файлов в папке установленного клиента Oracle (например, C:\app или C:\oracle), драйвер не может прочитать библиотеки локализации и падает в рекурсивную системную ошибку.

Решение: Перейдите в проводнике к корневой папке установленного клиента Oracle, откройте её "Свойства" -> вкладка "Безопасность". Нажмите кнопку "Изменить" и добавьте права "Чтение и выполнение" (Read & Execute) для группы пользователей "Прошедшие проверку" (Authenticated Users) или конкретного локального пользователя. Обязательно примените изменения ко всем дочерним объектам и перезагрузите компьютер.

Причина 2. Конфликт региональных настроек (NLS_LANG)

Если кодировка операционной системы не совпадает со значениями, ожидаемыми клиентом Oracle, инициализация сессии прерывается.

Решение: Откройте редактор реестра regedit и перейдите в ветку 32-битного окружения: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_... (или HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_... для 32-битных ОС). Найдите строковый параметр NLS_LANG и установите для него корректное значение русской локали, например: RUSSIAN_RUSSIA.CL8MSWIN1251.

Шаг 4. Вызов функции инициализации контекста Oracle

Во многих корпоративных системах (например, Oracle E-Business Suite — OEBS) после успешного открытия физического соединения требуется выполнить логическую авторизацию пользователя во внутреннем реестре пакетов СУБД. Нам необходимо запустить PL/SQL-функцию:

xxeq_interface.login(user_name, password) RETURN numeric

Для корректного вызова этой функции в среде 1С 7.7 мы задействуем объект ADODB.Command. Обратите внимание на важнейшее правило технологии ADO при работе с Oracle: возвращаемый параметр функции (ReturnValue) всегда должен создаваться и добавляться в коллекцию параметров самым первым по порядку! Только после него добавляются входные параметры.

Рассмотрим детальный пример реализации этого механизма:


Функция ВыполнитьАвторизациюВ_OEBS(Соединение, ИмяПользователя, Пароль)
    Команда = СоздатьОбъект("ADODB.Command");
    Команда.ActiveConnection = Соединение;
    Команда.CommandText = "xxeq_interface.login";
    Команда.CommandType = 4; // Соответствует системной константе adCmdStoredProc
    
    // 1. Создаем и добавляем параметр для возвращаемого значения (Index = 0)
    // Параметры метода CreateParameter: Имя, Тип (3 = adInteger), Направление (4 = adParamReturnValue)
    ПарамВозврат = Команда.CreateParameter("result", 3, 4);
    Команда.Parameters.Append(ПарамВозврат);
    
    // 2. Создаем и добавляем входящие параметры (имена должны точно соответствовать сигнатуре в СУБД)
    // Параметры: Имя, Тип (200 = adVarChar), Направление (1 = adParamInput), Размер, Значение
    ПарамUser = Команда.CreateParameter("user_name", 200, 1, 50, ИмяПользователя);
    Команда.Parameters.Append(ПарамUser);
    
    ПарамPass = Команда.CreateParameter("password", 200, 1, 50, Пароль);
    Команда.Parameters.Append(ПарамPass);
    
    Попытка
        Команда.Execute();
        Результат = Число(ПарамВозврат.Value);
        Возврат Результат;
    Исключение
        Сообщить("Ошибка вызова инициализирующей функции: " + ОписаниеОшибки(), "!");
        Возврат -1;
    КонецПопытки;
КонецФункции

Шаг 5. Получение и обработка данных (Recordset)

После того как соединение установлено и контекст сессии успешно проинициализирован функцией авторизации, мы можем выполнять SQL-запросы на выборку данных и переносить результаты в объекты 1С (например, в ТаблицаЗначений).

Разберем готовый шаблон функции чтения данных:


Процедура ЗагрузитьДанныеИзOracle()
    // Открываем соединение
    Соединение = СоздатьОбъект("ADODB.Connection");
    Соединение.Provider = "OraOLEDB.Oracle";
    Соединение.ConnectionString = "Data Source=MOON;User ID=XXXX;Password=xxxx;";
    
    Попытка
        Соединение.Open();
    Исключение
        Предупреждение("Не удалось открыть сессию с сервером Oracle!");
        Возврат;
    КонецПопытки;
    
    // Выполняем логический вход в систему
    РезультатВхода = ВыполнитьАвторизациюВ_OEBS(Соединение, "oebs_user", "oebs_pass");
    Если РезультатВхода <> 1 Тогда // Предположим, что 1 - признак успешного входа
        Предупреждение("Авторизация в пакете xxeq_interface отклонена СУБД!");
        Соединение.Close();
        Возврат;
    КонецЕсли;
    
    // Выполняем произвольный SQL-запрос
    Команда = СоздатьОбъект("ADODB.Command");
    Команда.ActiveConnection = Соединение;
    Команда.CommandType = 1; // adCmdText
    Команда.CommandText = "SELECT kod, nreg, name FROM kod_amort WHERE active = 1";
    
    Попытка
        Выборка = Команда.Execute();
    Исключение
        Предупреждение("Ошибка выполнения SQL-запроса: " + ОписаниеОшибки());
        Соединение.Close();
        Возврат;
    КонецПопытки;
    
    // Переносим результат выборки в Таблицу Значений 1С
    ТЗ = СоздатьОбъект("ТаблицаЗначений");
    ТЗ.НоваяКолонка("Код");
    ТЗ.НоваяКолонка("РегНомер");
    ТЗ.НоваяКолонка("Наименование");
    
    Если Выборка.EOF() = 0 Тогда
        Пока Выборка.EOF() = 0 Цикл
            ТЗ.НоваяСтрока();
            
            // Чтение значений полей через обращение к коллекции Fields
            ТЗ.Код = СокрЛП(Выборка.Fields.Item("kod").Value);
            ТЗ.РегНомер = Число(Выборка.Fields.Item("nreg").Value);
            ТЗ.Наименование = СокрЛП(Выборка.Fields.Item("name").Value);
            
            Выборка.MoveNext();
        КонецЦикла;
    КонецЕсли;
    
    // Закрываем выборку и соединение
    Выборка.Close();
    Соединение.Close();
    
    // Выводим полученную таблицу для анализа пользователю
    ТЗ.ВыбратьСтроку("Загруженные амортизационные коды из Oracle");
КонецПроцедуры

Используя предложенные методики, мы можем гибко управлять сессиями Oracle непосредственно из программного кода платформы 1С 7.7, обеспечивая высокую скорость обмена данными и корректную обработку транзакций и процедур авторизации.

← На главную