Еще раз о COM-соединениях

1. novatrade 02.03.20 22:51 Сейчас в теме
Честно говоря, не думал писать какие-либо заметки. Однако некоторые публикации подтолкнули меня к написанию этой заметки.
Не буду описывать всю последовательность своих шагов, как я к этому пришел. Сформулирую сразу вкратце свое решение:
1. На стороне Базы, которая выступает источником данных, располагаю модуль Обмен. В нем прописываю следующую функцию:

Функция ОбработкаЗапроса(МассивВходной,ТекстЗапроса)   Экспорт
	ПолученнаяСтруктура = ЗначениеИзСтрокиВнутр(МассивВходной);
	Запрос = Новый Запрос;     
	Запрос.Текст = ЗначениеИзСтрокиВнутр(ТекстЗапроса);
	Для Каждого Элемент из ПолученнаяСтруктура Цикл 
		Запрос.УстановитьПараметр(Элемент.Ключ,Элемент.Значение);
	КонецЦикла;
	Тбл = Запрос.Выполнить().Выгрузить();   
	Возврат ЗначениеВСтрокуВнутр(Тбл);                                                                
КонецФункции
Показать


В конфигурации, которая производит вызовы, создаю такой алгоритм вызова:
	Подключение = Новый COMОбъект("V83.COMConnector.1");
	Сервер		 = Справочники.ПараметрыПодключения.База.СерверДляПодключения;
	База 		 = Справочники.ПараметрыПодключения.База.ИмяБазы;
	Пользователь = Справочники.ПараметрыПодключения.База.ИмяПользователь;
	Пароль		 = Справочники.ПараметрыПодключения.База.ПарольПользователя;
	База 	 = Подключение.Connect("Srvr='"+Сервер+"'; Ref='"+База+"'; Usr='"+Пользователь+"'; Pwd='"+Пароль+"'");
	ТекстЗапроса =»(Ваш Запрос)»;
	СтруктураПередачи = новый Структура();
	….(создаю структуру, содержащую имена параметров и их значения для запроса)
	Результирующая таблица = ЗначениеИзСтрокиВнутр(База.Обмен. ОбработкаЗапроса (ЗначениеВСтрокуВнутр(ТекстЗапроса), ЗначениеВСтрокуВнутр(СтруктураПередачи)));
	Подключение = Неопределено;	
Показать


Такой подход позволил мне получить очень быстро результаты запроса и обрабатывать их в вызывающей базе, не используя COM-объекты.
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. duhin 03.03.20 06:05 Сейчас в теме
Не понял в чем профит
1.
>Подключение = Новый COMОбъект("V83.COMConnector.1");
>не используя COM-объекты.
тут противоречие какое то
2.Запрос можно выполнить на вызывающей стороне а затем сериализовать-десериализовать чтоб получить родную таблицу значений. Зачем что-то писать на принимающей стороне-неясно
3. Также непонятно при чем здесь скорость. Вариант в моем втором пункте будет выполнятся ровно столько же, только на стороне- сервере ничего писать не надо, код в одной функции, проще читается и обслуживается.
4. Nadushka74 5 03.03.20 09:06 Сейчас в теме
(2)
>Подключение = Новый COMОбъект("V83.COMConnector.1");
>не используя COM-объекты.
тут противоречие какое то


подключение есть, но вы обрабатываете не ?Com.Объект а родную структуру для вашей базы.

Иногда очень удобный механизм.
5. duhin 03.03.20 13:08 Сейчас в теме
(4)
    ВнешняяБаза = ...//Как у вас
    Запрос = ВнешняяБаза.NewObject("Запрос"); 
    Запрос.Текст= "...";
    тзнКом= Запрос.Выполнить().Выгрузить();
    тзн = ЗначениеИзСтроки(ВнешняяБаза.ЗначениеВСтроку(тзнКом));

И у вас родная структура вашей базы, и все хорошо)) И в базу- источник данных ничего толкать не нужно.
Другое дело с HTTP- WEB сервисами, там действительно достигается огромная экономия за счет того, что не надо стартовать клиента, поскольку создание ком объекта- по сути старт клиента 1с. Чтобы уменьшить расходы на создание КОМ соединения возможно хорошая идея кешировать комобъект- но тогда будет висеть лишнее соединение к серверу. HTTP сервисы(WEB-сервисы для нашей легаси 8.2) реально дают выигрыш в десятки раз, на своей шкуре это уже почувствовали, интенсивно на них переходим.
7. novatrade 03.03.20 20:56 Сейчас в теме
(2)
1. Если вы работали с COM соединением, то должны знать, что получите ответ, содержащий COM объекты, которые надо обрабатывать.
2. Интересно, как? То, что Вы пишете запрос на вызывающей стороне - совсем не значит, что он там выполняется. Выполняется
Насчет сериализации - а Вы пробовали тот алгоритм, который предлагаете?
3. Просто интересно, сколько у вас на объемах в несколько сотен тысяч записей займет времени передача данных и приведение их к таблице значений?
8. duhin 04.03.20 04:35 Сейчас в теме
(7) Передача данных откуда куда? В вашем и моем варианте происходит одно и тоже. Через ком объект создается клиентский сеанс к чужой базе. В нем выполняется запрос и получается таблица значений, в том сеансе. В том же сеансе тзн преобразуется в строку. и передается нам. Откуда, по вашему, появится разнице?
Впрочем, когда найду время, сделаю замер. Но сейчас мне непонятно, откуда появится разнице. Расходы на мой взгляд одинаковые, просто весь код в одном месте и не надо трогать базу источник, что важно, если она на поддержке.
3. xSavantx 25 03.03.20 09:01 Сейчас в теме
Замеры делали? Можете выложить?
6. novatrade 03.03.20 20:41 Сейчас в теме
(3)нет, замеры не делал. Помню, что запрос и перекачка порядка 850 тыс. строк таблицы значений заняла несколько минут. Сейчас особо и проверить не на чем, т.к. ни задач ни баз такого объема под рукой нет. Да и времени как всегда - дефицит.
9. duhin 04.03.20 05:55 Сейчас в теме
И да, по поводу того, работал ли я с ком соединением. Примитивные типы- строки, даты, числа- не надо сериализовать, они и так прекрасно передаются. Это я вот про это
Запрос.Текст = ЗначениеИзСтрокиВнутр(ТекстЗапроса);
10. duhin 04.03.20 06:22 Сейчас в теме
Пример сделал, работает одинаково. На 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("Запрос"); 
	Запрос.Текст = ТекстЗапроса;
	РезультирующаяТаблица = ЗначениеИзСтрокиВнутр(База.ЗначениеВСтрокуВнутр(Запрос.Выполнить().Выгрузить()));
    Подключение = Неопределено;
	Сообщить("Потрачено мс" + (ТекущаяУниверсальнаяДатаВМиллисекундах()-старт));
	ОткрытьЗначение(РезультирующаяТаблица);
КонецПроцедуры
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот