При интеграции 1С со сторонними базами данных (Oracle, MS SQL, PostgreSQL) разработчики часто сталкиваются с необходимостью сопоставить данные из внешнего источника с объектами текущей информационной базы (например, получить ссылки справочников 1С по внешним кодам или идентификаторам). Стандартный подход с выгрузкой результата запроса внешнего источника в ТаблицаЗначений с последующей передачей во второй запрос в виде временной таблицы создает избыточную нагрузку на оперативную память сервера, особенно при больших объемах данных. Разберем, как устроен этот механизм, выясним причины ограничений платформы и рассмотрим оптимальные способы стыковки разнородных данных.
Платформа 1С принципиально разделяет контексты выполнения запросов. Выясним, почему стандартный язык запросов 1С выдает ошибку "Получение данных из нескольких источников данных недопустимо" при попытке соединения:
ВнешнийИсточникДанных.<ИмяИсточника>.ВременнаяТаблица.<ИмяВТ> предназначена исключительно для промежуточных вычислений внутри самой внешней СУБД в рамках единого пакета запросов к этому внешнему источнику. Получить доступ к такой временной таблице из запроса к основной базе 1С технически невозможно.Наиболее универсальным и производительным встроенным инструментом для решения этой задачи является система компоновки данных. СКД умеет работать с гетерогенными источниками данных и соединять их в оперативной памяти сервера с оптимизацией запросов.
Разберем по шагам настройку схемы компоновки:
Набор данных - запрос к таблицам 1С (например, к справочнику Номенклатура), выбираем необходимые поля (Ссылка, Код, Артикул).Набор данных - запрос, указав в качестве источника данных внешний источник. В тексте запроса выбираем таблицы внешнего источника (например, цены, остатки или штрихкоды из базы Oracle).Код).Если соединенные данные нужны не для отображения в отчете, а для программной обработки в коде (например, для регламентной синхронизации), выполним схему компоновки программно с выводом в коллекцию значений:
// Создаем схему и настройки компоновки
СхемаКомпоновкиДанных = ПолучитьМакет("СхемаСтыковкиДанных");
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
// Инициализируем компоновщик макета
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
// Выполняем компоновку данных
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
// Выводим результат напрямую в ТаблицуЗначений без построения отчета
ТаблицаРезультат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Рассмотрим встроенный механизм метаданных внешних источников. Если во внешней таблице хранится идентификатор объекта 1С (код, артикул или строковое представление УИД), платформа позволяет настроить связь без использования сложных конструкций:
СправочникСсылка.Номенклатура или СправочникСсылка.Контрагенты).Проанализируем архитектурное решение для высоконагруженных систем. Если требуется максимальная скорость выборки без перекладывания нагрузки на сервер 1С, соединение баз можно вынести на уровень самих СУБД:
VIEW), которое нативно соединяет локальные таблицы с таблицами информационной базы 1С по ключевым полям.Если задача заключается в периодической загрузке большого массива информации и использование СКД или межсерверных связей не подходит, оптимизируем ручную обработку. Вместо получения всего массива данных за один раз разобьем выборку на порции:
// Задаем размер пакета для снижения нагрузки на память
РазмерПакета = 5000;
ПоследнийИД = 0;
Пока Истина Цикл
ЗапросВИД = Новый Запрос;
ЗапросВИД.Текст =
"ВЫБРАТЬ ПЕРВЫЕ " + Строка(РазмерПакета) + "
| ВнешняяТаблица.ID КАК ID,
| ВнешняяТаблица.КодОбъекта КАК КодОбъекта,
| ВнешняяТаблица.Количество КАК Количество
|ИЗ
| ВнешнийИсточникДанных.ВнешняяБаза.Таблица.Данные КАК ВнешняяТаблица
|ГДЕ
| ВнешняяТаблица.ID > &ПоследнийИД
|УПОРЯДОЧИТЬ ПО
| ID";
ЗапросВИД.УстановитьПараметр("ПоследнийИД", ПоследнийИД);
Выборка = ЗапросВИД.Выполнить().Выбрать();
Если Выборка.Количество() = 0 Тогда
Прервать;
КонецЕсли;
Пока Выборка.Следующий() Цикл
ПоследнийИД = Выборка.ID;
// Выполняем точечный поиск или запись в базу 1С
Ссылка1С = Справочники.Номенклатура.НайтиПоКоду(Выборка.КодОбъекта);
// Обработка полученных данных
КонецЦикла;
КонецЦикла;
Пошаговая выборка исключает переполнение оперативной памяти рабочего процесса 1С и обеспечивает стабильную синхронизацию при любых объемах внешней базы данных.