Прямые запросы с типизацией
Результат выполнения прямых запросов теперь можно возвращать через объект "РезультатЗапроса" с типизацией.
Цели
Возможность формирования прямых запросов к БД 1с вечно мучила умы разработчиков. У каждого свои цели и задачи, но все эти попытки были направлены на то чтобы снять тот уровень абстракции, который предлагает 1С и получить данные без ограничения. Со временем некоторые, талантливые головы открыли нам описания таблиц SQL, и формировать запросы осталось только делом техники. Однако построенные таким образом запросы могли быть более менее пригодны из сторонних систем. Потому как они они не могли работать с прикладными типами объектов (то есть запрос не мог вернуть ссылку на элемент справочника,документа .. и т.д.) в чем он и проигрывал своему оригинальному собрату. Таким образом прямые запросы на 8 так и не прижились в повседневной разработке конфигураций на 1с, из за следующих своих недостатков:
- невозможность работы с прикладными типами объектов;
- длительное возвращение результатов запроса по средством перебора всех записей RecordSet; (можно обойти используя ВК GameWithFire)
- отсутствие вменяемого визуального конструктора запросов;
однако для определенных специфических задач, связанных с интеграцией из различных источников данных, прямые запросы в 8 используются. Ситуация у младшего брата 8 -7.7 сложилось более благополучно, как говорится "Не было счастья, да не счастье помогло". Дак вот тем самым не счастьем в 7.7 был ее так называемый (у кого язык повернулся) "язык запросов". Те кто работал на 7.7 и 8 меня поймут. Это "язык запросов" похож на все что угодно, кроме запроса. Наигравшись с такими "запросами" вдоволь была создана ВК 1С++ которая позволяет выполнять прямые запросы. Все полюсы этих запросов очевидны из текста запроса, кроме типизирующих псевдонимов это чистый SQL. К тому же все недостатки прямых запросов заявленные выше, в 1с++ обошли, в том числе и конструктор запросов.
Период с ДатаПрошлогоПериода по ДатаПрошлогоПериода; ВидРасч = ЖурналРасчетов.Зарплата.ВидРасч; Объект = ЖурналРасчетов.Зарплата.Объект; Результат = ЖурналРасчетов.Зарплата.Результат; ПериодДействия = ЖурналРасчетов.Зарплата.ПериодДействия; ДатаОкончания = ЖурналРасчетов.Зарплата.ДатаОкончания; Группировка Объект Без Групп; Условие(ВидРасч = ВидРасчета.НДФЛ); Условие(Результат <> 0); Условие(ДатаОкончания <> ДатаПрошлогоПериода)
|
SELECT Контрагенты.ID [Ссылка $Справочник.Контрагенты] , Контрагенты.ISMARK ПометкаУдаления , Контрагенты.PARENTID [Родитель $Справочник.Контрагенты] , Контрагенты.ISFOLDER ЭтоГруппа , Контрагенты.CODE Код , Контрагенты.DESCR Наименование , $Контрагенты.ВидКонтрагента [ВидКонтрагента $Перечисление.ВидыКонтрагентов] , $Контрагенты.ПолнНаименование ПолнНаименование , $Контрагенты.ОсновнойДоговор [ОсновнойДоговор $Справочник.Договоры] , $Контрагенты.ОсновнойСчет [ОсновнойСчет $Справочник.РасчетныеСчета] , $Контрагенты.ОКПО ОКПО FROM $Справочник.Контрагенты AS Контрагенты INNER JOIN $Справочник.Контрагенты AS Контрагенты1 ON Контрагенты.DESCR = Контрагенты1.DESCR Where (Контрагенты.PARENTID=' K0' or Контрагенты.PARENTID=' jj') and (Контрагенты1.PARENTID=' K0' or Контрагенты1.PARENTID=' jj')
| Нашей задачей в этой статье будет получение аналогичного результат прямых запросов на 1с++, только в контексте 8.1 и старше.
Общий подход
В изложенном подходе не будет использоваться внешних компонент. Пока работа данного подхода проверена на MSSQL 2000 возможность работы в других СУБД пока не изучались . Достоверно известно что описанный здесь подход, ПОКА не будет работать в MSSQL 2005. Основная идея реализации будет крутится вокруг временных таблиц, и возможности 1с создавать и возвращать данные из них (Временных таблиц). Обобщенно подход можно представить в виде следующей последовательности.
Средствами 1С создается временная таблица. Временная таблица должна иметь такую структуру колонок и их типов, которую мы хотим получить по результатам выполнения запроса. Запрос = Новый Запрос("ВЫБРАТЬ | ТЗ_Null.* |ПОМЕСТИТЬ ТЗ |ИЗ | &ТЗ КАК ТЗ_Null"); МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц; ТЗ=Новый ТаблицаЗначений; Запрос.УстановитьПараметр("ТЗ", ТЗ); РезультатЗапроса = Запрос.Выполнить(); |
Созданная временная таблица будет локальной (#tt1), и соответственно будет доступна только из той сесии, в которой она была создана. На этом этапе необходимо будет сделать из это локальной временной таблицы глобальную (##tt). Подробное описание этого процесса приведено в статье Смирнова Андрея. В нашем случае задача еще усложняется тем что мы не знаем имени временной таблицы. Поэтому при изменении имени используется следующий запрос (пример):
DECLARE @table_name varchar(100) --Перименовывем таблицу set @table_name = 'temp_'+Left(cast(newid() as varchar(36)),8) Select @table_name as table_name update tempdb..sysobjects set name = @table_name where id in (SELECT top 1 id FROM tempdb..sysobjects WHERE Len(Name)=128 and info >= 8 and CRDate >= 29.04.2008 15:15:15)
| |
Теперь когда у нас есть ~глобальная временная таблица (доступна из сеанса 1с и из любого подключения к MSSQL) остается только делом техники наполнить ее необходимыми данными.
INSERT Into temp..##tt Select * From dbo._Reference32
|
Здесь и далее имя временной таблицы будет ##tt, однако оно отличается от реального
set @table_name = 'temp_'+Left(cast(newid() as varchar(36)),8) преобразование в реальное имя осуществляется непосредственно перед выполнением запроса. Такая "конспирация" нужна, потому что мы текст запроса задаем раньше чем узнаем имя временной таблицы | |
Теперь когда у нас временная таблица наполнена необходимыми данными вернем результат запроса в текущее соединение 1С. Обращаю внимание что в данном случае нужно использовать именно тот менеджер временных таблиц в котором мы и создавали временную таблицу с заданной структурой и типами колонок.
Запрос.Текст ="ВЫБРАТЬ | ТЗ.* |ИЗ | ТЗ КАК ТЗ"; Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц; мРезЗапроса = Запрос.Выполнить();
|
Реализация
Основными сложностями в реализации будет правильно продекларировать типы колонок временной таблиц..... Читать полностью
http://groups.google.ru/group/enterprise-integrator
Оценка сообщества
Плюсы (+18):
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
| Добавить плюс Добавить минус
Комментарии (8)
|
Реализация как всегда в новой версии Ei http://infostart.ru/profile/4379/projects/782/