Подключение 1С к Oracle чаще всего делают через COM-объект ADODB.Connection: на сервере 1С ставится провайдер Oracle (OraOLEDB или ODBC-драйвер), из строки подключения открывается соединение, запросы на чтение выполняются методом Execute с обходом Recordset, а запись — через ADODB.Command с параметрами. Второй вариант — внешние источники данных 1С через ODBC: таблицы Oracle становятся доступны в языке запросов 1С и работают в том числе на сервере под Linux.

Ниже — оба способа, рабочий код с параметризованными запросами и транзакциями, и список ошибок, которые я чаще всего вижу в чужих интеграциях с Oracle.

Какой способ выбрать

ADODB (COM)Внешние источники данных
ОС сервера 1СТолько WindowsWindows и Linux (через ODBC)
Где писать запросыSQL Oracle строкойЯзык запросов 1С и SQL
Запись в OracleДа, любой SQLДа, с ограничениями, через объекты или SQL
НастройкаКодМетаданные конфигурации + код
Когда удобноНесколько точечных запросов, процедуры OracleРегулярное чтение таблиц, отчёты, соединения с данными 1С

Для разовой выгрузки или пары интеграционных процедур ADODB проще. Если данные Oracle нужны в отчётах на СКД или сервер 1С на Linux — смотрите в сторону внешних источников.

Шаг 1. Провайдер на сервере 1С

Код с COMОбъект выполняется на сервере 1С (в клиент-серверном варианте), значит провайдер нужен на сервере 1С, а не на компьютере пользователя. И той же разрядности, что и процесс сервера: 64-битный rphost не увидит 32-битный провайдер.

Варианты:

  • OraOLEDB — OLE DB провайдер Oracle из клиента Oracle. Основной выбор.
  • ODBC-драйвер Oracle через провайдер MSDASQL — если уже настроен DSN.
  • MSDAORA (Microsoft) — устаревший, 64-битной версии нет. Для новых интеграций не используйте.

Проверить установленные провайдеры удобно файлом UDL: создайте пустой текстовый файл с расширением .udl, откройте его — на вкладке «Поставщик данных» будет список провайдеров. Только запускайте его под той же разрядностью, что и сервер 1С.

Шаг 2. Строка подключения

Тот же UDL-файл помогает собрать строку подключения: на вкладке «Соединение» укажите сервер (TNS-алиас или строку EZCONNECT), пользователя и пароль, нажмите «Проверить соединение» и сохраните. Если открыть файл блокнотом, в нём будет готовая строка.

Типичные строки:

text
Provider=OraOLEDB.Oracle;Data Source=ORCL_PROD;User Id=U_1C;Password=***;
Provider=MSDASQL.1;Data Source=OracleDSN;User ID=U_1C;Password=***;

Для интеграции заведите в Oracle отдельного пользователя с правами только на нужные представления и таблицы. Читать — из представлений (VIEW), писать — в отдельные таблицы-«входящие» или через процедуры: так администратор Oracle контролирует, что именно меняет 1С.

Шаг 3. Соединение

1С
// Открывает соединение с Oracle. Вызывающий код обязан закрыть его.
//
// Возвращаемое значение:
//  COMОбъект - открытое ADODB.Connection.
//
Функция ОткрытьСоединениеOracle() Экспорт

	СтрокаПодключения = СтрокаПодключенияOracle(); // читается из защищённого хранилища

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

	Возврат Соединение;

КонецФункции

Ошибку подключения здесь не глушу: пусть вызывающий код решает, что делать, а в журнал регистрации попадёт полный текст исключения. Функция «сообщить пользователю и вернуть Неопределено» на сервере, где работает регламентное задание, означает, что об ошибке никто не узнает.

Пароль не храните в коде. В конфигурациях на БСП для этого есть безопасное хранилище (ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище и ПрочитатьДанныеИзБезопасногоХранилища).

Шаг 4. Чтение данных

1С
// Читает акты по идентификатору расчёта из представления Oracle.
Функция АктыРасчета(ИдентификаторРасчета) Экспорт

	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить("Контрагент", Новый ОписаниеТипов("Строка"));
	Результат.Колонки.Добавить("НомерАкта", Новый ОписаниеТипов("Строка"));
	Результат.Колонки.Добавить("ДатаАкта", Новый ОписаниеТипов("Дата"));

	Соединение = ОткрытьСоединениеOracle();
	Попытка
		Команда = НоваяКоманда(Соединение,
			"select PARTNER, ACTNUMBER, ACTDATE from U_1C.V_PAYACT where CALCULATIONID = ?");
		ДобавитьПараметр(Команда, ИдентификаторРасчета, 200, 64); // adVarChar

		Выборка = Команда.Execute();
		Пока Не Выборка.EOF Цикл
			Строка = Результат.Добавить();
			Строка.Контрагент = ЗначениеПоля(Выборка, "PARTNER", "");
			Строка.НомерАкта = ЗначениеПоля(Выборка, "ACTNUMBER", "");
			Строка.ДатаАкта = ЗначениеПоля(Выборка, "ACTDATE", Дата(1, 1, 1));
			Выборка.MoveNext();
		КонецЦикла;
		Выборка.Close();
		Соединение.Close();
	Исключение
		ЗакрытьБезопасно(Соединение);
		ВызватьИсключение;
	КонецПопытки;

	Возврат Результат;

КонецФункции

// Возвращает значение поля Recordset, заменяя NULL на значение по умолчанию.
Функция ЗначениеПоля(Выборка, ИмяПоля, ПоУмолчанию)

	Значение = Выборка.Fields(ИмяПоля).Value;
	Возврат ?(Значение = Null, ПоУмолчанию, Значение);

КонецФункции

Обратите внимание на NULL: пустые значения из Oracle приходят как Null, и прямое присваивание в колонку с типом «Дата» или «Число» даст не то, что ждёте.

Шаг 5. Запись с параметрами и транзакцией

Склейка SQL из строк — главный источник ошибок в таких интеграциях: номер договора с апострофом ломает запрос, формат даты зависит от настроек сессии, а данные пользователя становятся частью SQL. Используйте ADODB.Command с параметрами.

1С
// Создаёт команду ADODB с текстом запроса.
Функция НоваяКоманда(Соединение, ТекстЗапроса)

	Команда = Новый COMОбъект("ADODB.Command");
	Команда.ActiveConnection = Соединение;
	Команда.CommandText = ТекстЗапроса;
	Команда.CommandType = 1; // adCmdText
	Возврат Команда;

КонецФункции

// Добавляет входной параметр команды.
// Тип: 200 — adVarChar, 135 — adDBTimeStamp, 131 — adNumeric.
Процедура ДобавитьПараметр(Команда, Значение, ТипADO, Размер = 0)

	Параметр = Команда.CreateParameter(, ТипADO, 1, Размер, Значение); // 1 — adParamInput
	Команда.Parameters.Append(Параметр);

КонецПроцедуры

// Записывает регистрационные данные договоров в Oracle одной транзакцией.
Процедура ЗаписатьРегистрацииВOracle(Регистрации) Экспорт

	Соединение = ОткрытьСоединениеOracle();
	Соединение.BeginTrans();
	Попытка
		Для Каждого Регистрация Из Регистрации Цикл
			Команда = НоваяКоманда(Соединение,
				"insert into U_1C.REG_IN (REGNUMBER, REGDATE, DOCTYPE_GUID) values (?, ?, ?)");
			ДобавитьПараметр(Команда, Регистрация.Номер, 200, 50);
			ДобавитьПараметр(Команда, Регистрация.Дата, 135);
			ДобавитьПараметр(Команда, Строка(Регистрация.ВидДокументаGUID), 200, 36);
			Команда.Execute();
		КонецЦикла;
		Соединение.CommitTrans();
		Соединение.Close();
	Исключение
		Соединение.RollbackTrans();
		ЗакрытьБезопасно(Соединение);
		ВызватьИсключение;
	КонецПопытки;

КонецПроцедуры

Процедура ЗакрытьБезопасно(Соединение)

	Попытка
		Соединение.Close();
	Исключение
		// Соединение уже закрыто или разорвано — нечего делать.
	КонецПопытки;

КонецПроцедуры

Транзакция на стороне Oracle гарантирует, что пачка запишется целиком или не запишется совсем. С транзакцией 1С она не связана: если после записи в Oracle упадёт запись документа в 1С, откатывать Oracle придётся отдельно. Для надёжных сценариев делайте обмен идемпотентным — с уникальным ключом записи в Oracle и проверкой на повтор.

Подключение 1С к Oracle: параметризованные запросы как контрольный пункт на мосту между базами
Подключение 1С к Oracle: параметризованные запросы как контрольный пункт на мосту между базами

Вариант без COM: внешние источники данных

Внешние источники данных — объект метаданных, который описывает таблицы сторонней СУБД. Подключение идёт через ODBC, поэтому работает и на сервере 1С под Linux (с установленным ODBC-драйвером Oracle и unixODBC).

Порядок:

  1. В конфигурации (или расширении) добавьте внешний источник данных и загрузите описание нужных таблиц и представлений Oracle.
  2. Задайте строку соединения ODBC — в конфигураторе для отладки и программно для рабочей базы через ВнешниеИсточникиДанных.ИмяИсточника.УстановитьОбщиеПараметрыСоединения.
  3. Читайте данные обычным запросом 1С: ИЗ ВнешнийИсточникДанных.Oracle.Таблица.V_PAYACT.

Плюс — данные Oracle можно соединять с данными 1С в запросах и использовать в отчётах на СКД. Минус — сложные операции записи и вызовы процедур Oracle всё равно удобнее делать прямым SQL.

Типичные ошибки

  • Провайдер стоит у пользователя, а не на сервере. В клиент-серверной базе COM-объект создаётся на сервере 1С.
  • Разрядность. 32-битный провайдер при 64-битном сервере 1С — «Класс не зарегистрирован» или «Провайдер не найден».
  • SQL склеивается строкой. Ошибки на кавычках, датах и риск инъекций. Только параметры.
  • Соединение не закрывается при ошибке. Через несколько дней в Oracle заканчиваются сессии.
  • Ошибка глушится сообщением пользователю. В регламентном задании её никто не увидит — пишите в журнал регистрации и пробрасывайте исключение.
  • Пароль в коде. Попадает в хранилище конфигурации и выгрузки.
  • Права «на всё». Пользователь интеграции с правами владельца схемы — плохая идея; давайте доступ только к нужным объектам.
Интеграция с Oracle — это прежде всего договорённость с администратором Oracle: какие представления читаем, куда пишем и что делаем при ошибке. Код по сравнению с этим простой.

Интеграции 1С с внешними базами данных, в том числе Oracle и MS SQL, я делаю в рамках интеграции 1С по API и обмена между базами; если сервер 1С переезжает на Linux, заранее закладываю переход с ADODB на ODBC в рамках работ по серверу 1С.

Итог

  • Провайдер Oracle нужен на сервере 1С и той же разрядности, что и процесс сервера; MSDAORA не используйте.
  • Строку подключения удобно собрать и проверить через UDL-файл.
  • Читайте через Recordset с обработкой Null, пишите через ADODB.Command с параметрами и транзакцией.
  • Всегда закрывайте соединение, в том числе при исключении, и не храните пароль в коде.
  • На Linux и для отчётов используйте внешние источники данных через ODBC.