Еще раз о COM-соединениях
Честно говоря, не думал писать какие-либо заметки. Однако некоторые публикации подтолкнули меня к написанию этой заметки.
Не буду описывать всю последовательность своих шагов, как я к этому пришел. Сформулирую сразу вкратце свое решение:
1. На стороне Базы, которая выступает источником данных, располагаю модуль Обмен. В нем прописываю следующую функцию:
В конфигурации, которая производит вызовы, создаю такой алгоритм вызова:
Такой подход позволил мне получить очень быстро результаты запроса и обрабатывать их в вызывающей базе, не используя COM-объекты.
Не буду описывать всю последовательность своих шагов, как я к этому пришел. Сформулирую сразу вкратце свое решение:
1. На стороне Базы, которая выступает источником данных, располагаю модуль Обмен. В нем прописываю следующую функцию:
Функция ОбработкаЗапроса(МассивВходной,ТекстЗапроса) Экспорт
ПолученнаяСтруктура = ЗначениеИзСтрокиВнутр(МассивВходной);
Запрос = Новый Запрос;
Запрос.Текст = ЗначениеИзСтрокиВнутр(ТекстЗапроса);
Для Каждого Элемент из ПолученнаяСтруктура Цикл
Запрос.УстановитьПараметр(Элемент.Ключ,Элемент.Значение);
КонецЦикла;
Тбл = Запрос.Выполнить().Выгрузить();
Возврат ЗначениеВСтрокуВнутр(Тбл);
КонецФункции
ПоказатьВ конфигурации, которая производит вызовы, создаю такой алгоритм вызова:
Подключение = Новый COMОбъект("V83.COMConnector.1");
Сервер = Справочники.ПараметрыПодключения.База.СерверДляПодключения;
База = Справочники.ПараметрыПодключения.База.ИмяБазы;
Пользователь = Справочники.ПараметрыПодключения.База.ИмяПользователь;
Пароль = Справочники.ПараметрыПодключения.База.ПарольПользователя;
База = Подключение.Connect("Srvr='"+Сервер+"'; Ref='"+База+"'; Usr='"+Пользователь+"'; Pwd='"+Пароль+"'");
ТекстЗапроса =»(Ваш Запрос)»;
СтруктураПередачи = новый Структура();
….(создаю структуру, содержащую имена параметров и их значения для запроса)
Результирующая таблица = ЗначениеИзСтрокиВнутр(База.Обмен. ОбработкаЗапроса (ЗначениеВСтрокуВнутр(ТекстЗапроса), ЗначениеВСтрокуВнутр(СтруктураПередачи)));
Подключение = Неопределено;
ПоказатьТакой подход позволил мне получить очень быстро результаты запроса и обрабатывать их в вызывающей базе, не используя COM-объекты.
Ответы
В избранное
Подписаться на ответы
Сортировка:
Древо развёрнутое
Свернуть все
Не понял в чем профит
1.
>Подключение = Новый COMОбъект("V83.COMConnector.1");
>не используя COM-объекты.
тут противоречие какое то
2.Запрос можно выполнить на вызывающей стороне а затем сериализовать-десериализовать чтоб получить родную таблицу значений. Зачем что-то писать на принимающей стороне-неясно
3. Также непонятно при чем здесь скорость. Вариант в моем втором пункте будет выполнятся ровно столько же, только на стороне- сервере ничего писать не надо, код в одной функции, проще читается и обслуживается.
1.
>Подключение = Новый COMОбъект("V83.COMConnector.1");
>не используя COM-объекты.
тут противоречие какое то
2.Запрос можно выполнить на вызывающей стороне а затем сериализовать-десериализовать чтоб получить родную таблицу значений. Зачем что-то писать на принимающей стороне-неясно
3. Также непонятно при чем здесь скорость. Вариант в моем втором пункте будет выполнятся ровно столько же, только на стороне- сервере ничего писать не надо, код в одной функции, проще читается и обслуживается.
(4)
И у вас родная структура вашей базы, и все хорошо)) И в базу- источник данных ничего толкать не нужно.
Другое дело с HTTP- WEB сервисами, там действительно достигается огромная экономия за счет того, что не надо стартовать клиента, поскольку создание ком объекта- по сути старт клиента 1с. Чтобы уменьшить расходы на создание КОМ соединения возможно хорошая идея кешировать комобъект- но тогда будет висеть лишнее соединение к серверу. HTTP сервисы(WEB-сервисы для нашей легаси 8.2) реально дают выигрыш в десятки раз, на своей шкуре это уже почувствовали, интенсивно на них переходим.
ВнешняяБаза = ...//Как у вас
Запрос = ВнешняяБаза.NewObject("Запрос");
Запрос.Текст= "...";
тзнКом= Запрос.Выполнить().Выгрузить();
тзн = ЗначениеИзСтроки(ВнешняяБаза.ЗначениеВСтроку(тзнКом));
И у вас родная структура вашей базы, и все хорошо)) И в базу- источник данных ничего толкать не нужно.
Другое дело с HTTP- WEB сервисами, там действительно достигается огромная экономия за счет того, что не надо стартовать клиента, поскольку создание ком объекта- по сути старт клиента 1с. Чтобы уменьшить расходы на создание КОМ соединения возможно хорошая идея кешировать комобъект- но тогда будет висеть лишнее соединение к серверу. HTTP сервисы(WEB-сервисы для нашей легаси 8.2) реально дают выигрыш в десятки раз, на своей шкуре это уже почувствовали, интенсивно на них переходим.
(2)
1. Если вы работали с COM соединением, то должны знать, что получите ответ, содержащий COM объекты, которые надо обрабатывать.
2. Интересно, как? То, что Вы пишете запрос на вызывающей стороне - совсем не значит, что он там выполняется. Выполняется
Насчет сериализации - а Вы пробовали тот алгоритм, который предлагаете?
3. Просто интересно, сколько у вас на объемах в несколько сотен тысяч записей займет времени передача данных и приведение их к таблице значений?
1. Если вы работали с COM соединением, то должны знать, что получите ответ, содержащий COM объекты, которые надо обрабатывать.
2. Интересно, как? То, что Вы пишете запрос на вызывающей стороне - совсем не значит, что он там выполняется. Выполняется
Насчет сериализации - а Вы пробовали тот алгоритм, который предлагаете?
3. Просто интересно, сколько у вас на объемах в несколько сотен тысяч записей займет времени передача данных и приведение их к таблице значений?
(7) Передача данных откуда куда? В вашем и моем варианте происходит одно и тоже. Через ком объект создается клиентский сеанс к чужой базе. В нем выполняется запрос и получается таблица значений, в том сеансе. В том же сеансе тзн преобразуется в строку. и передается нам. Откуда, по вашему, появится разнице?
Впрочем, когда найду время, сделаю замер. Но сейчас мне непонятно, откуда появится разнице. Расходы на мой взгляд одинаковые, просто весь код в одном месте и не надо трогать базу источник, что важно, если она на поддержке.
Впрочем, когда найду время, сделаю замер. Но сейчас мне непонятно, откуда появится разнице. Расходы на мой взгляд одинаковые, просто весь код в одном месте и не надо трогать базу источник, что важно, если она на поддержке.
Пример сделал, работает одинаково. На 30 тыщах строчек проверил, возвращает в обоих ваиантах за секунду, плюс минус два процента. 66% времени тратится на метод connect- запуск приложения, как я и писал
Процедура КнопкаВыполнитьНажатие(Кнопка)
старт=ТекущаяУниверсальнаяДатаВМиллисекундах();
Подключение = Новый COMОбъект("V83.COMConnector.1");
База = Подключение.Connect("File=""C:\001\ТестКОМ_Источник"";");
ТекстЗапроса = "Выбрать * Из РегистрСведений.РегистрСведений1 как т1";
РезультирующаяТаблица = ЗначениеИзСтрокиВнутр(База.КомСервер.ОбработкаЗапроса(ТекстЗапроса));
Подключение = Неопределено;
Сообщить("Потрачено мс" + (ТекущаяУниверсальнаяДатаВМиллисекундах()-старт));
ОткрытьЗначение(РезультирующаяТаблица);
КонецПроцедуры
Процедура ОсновныеДействияФормыкнопка2(Кнопка)
старт=ТекущаяУниверсальнаяДатаВМиллисекундах();
Подключение = Новый COMОбъект("V83.COMConnector.1");
База = Подключение.Connect("File=""C:\001\ТестКОМ_Источник"";");
ТекстЗапроса = "Выбрать * Из РегистрСведений.РегистрСведений1 как т1";
Запрос = База.NewObject("Запрос");
Запрос.Текст = ТекстЗапроса;
РезультирующаяТаблица = ЗначениеИзСтрокиВнутр(База.ЗначениеВСтрокуВнутр(Запрос.Выполнить().Выгрузить()));
Подключение = Неопределено;
Сообщить("Потрачено мс" + (ТекущаяУниверсальнаяДатаВМиллисекундах()-старт));
ОткрытьЗначение(РезультирующаяТаблица);
КонецПроцедуры
Показать