Главная » Статьи » "1С" Програмирование

Скачивать материалы с сайта, могут только зарегистрированные пользователи.
Для регистрации заполните два поля ниже!

Через минуту Вы получите "Гостевой доступ"




Прямые запросы с типизацией
Прямые запросы с типизацией
  
Результат выполнения прямых запросов теперь можно возвращать через объект "РезультатЗапроса" с типизацией.
 

Цели


Возможность формирования прямых запросов к БД 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)

1.
 
07.05.2008 11:11:33

Реализация как всегда в новой версии Ei http://infostart.ru/profile/4379/projects/782/

2.
 
07.05.2008 12:00:15
Изучал данный вопрос год назад при написании SQLPlus:
http://infostart.ru/profile/6612/projects/839/

Пришел к следующим выводам:
В MS SQL 2000 вполне реально сделать. (под рукой нет - не проверял).
В MS SQL 2005 нет допуска на запись в системные таблицы.Только в Single_User режиме, что
по определению делает такую задачу невозможной.

ссылка на обсуждение с sql.ru
http://sql.ru/forum/actualthread.aspx?tid=408724
 

статья с сайта: www.infostart.ru

Категория: "1С" Програмирование | Добавил: c1 (2009 Февраль 21)
Просмотров: 2532 | Теги: Прямые запросы с типизацией | Рейтинг: 0.0/0

Выразить благодарность - Поделиться с друзьями!

 

Здесь все о технической стороне 1С!

 

Узнай, как правильно администрировать 1С Предприятие
Регистрируйся на бесплатный 7-ми дневный курс сейчас:

Ваш E-Mail в безопасности



Всего комментариев: 0
avatar