Olark Livehelp
ГлавнаяРегистрацияВход Все для комфортного обучения 1С Воскресенье, 20.05.2012, 07:16
  Публикации Приветствую Вас Гость | RSS

 
 
Главная » Статьи » Статьи по 1С

Пакетные запросы
Введение

В системе программ 1С:Предприятие 8, начиная с версии 8.1.11, появилось понятие «Пакетные запросы». По своей сути пакетные запросы предоставляют новый подход к формированию сложных запросов.

История развития запросов

Простые запросы

Разберем, как изменялся (скорее дополнялся) синтаксис текстов запросов на простом примере: Проводится документ «Расходная» содержащая в табличной части «Товары» список продаваемых товаров и количество. При проведении такого документа необходимо обеспечить контроль отрицательных остатков хранящихся в регистре накопления остатков «ОстаткиТоваров».

Рисунок 1

Структура конфигурации представлена на рисунке (см. Рисунок 1).

Сформируем запрос к табличной части документа и виртуальной таблице «Остатки» регистра накопления. Учтем возможные дубли строк в документе, для этого произведем группирование записей.

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

Запрос = Новый Запрос;

Запрос.Текст = "

|ВЫБРАТЬ

| Док.Номенклатура,

| СУММА(Док.Количество) КАК Док_Количество,

| МИНИМУМ( ЕСТЬNULL(Рег.КоличествоОстаток,0)) КАК Рег_Количество

|ИЗ

| Документ.Расходная.Товары КАК Док

| ЛЕВОЕ СОЕДИНЕНИЕ

| РегистрНакопления.ОстаткиТоваров.Остатки() КАК Рег

| ПО

| Док.Номенклатура = Рег.Номенклатура

|ГДЕ

| Ссылка = &Ссылка

|СГРУППИРОВАТЬ ПО Док.Номенклатура";

Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатЗапроса = Запрос.Выполнить();

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

//Проверка отрицательных остатков

//Проведение по регистру

КонецЦикла;

КонецПроцедуры

Естественно приведенный запрос абсолютно не оптимален. С помощью вложенных запросов оптимизируем его: Произведем группирование табличной части документа до соединения с таблицей остатков, в параметры виртуальной таблицы передадим список товаров как значение условия для расчета остатков. В итоге наш запрос примет следующий вид:

|ВЫБРАТЬ

| Док.Номенклатура,

| Док.Количество КАК Док_Количество,

| ЕСТЬNULL(Рег.КоличествоОстаток,0) КАК Рег_Количество

|ИЗ

| (ВЫБРАТЬ

| Номенклатура, СУММА(Количество) КАК Количество

| ИЗ Документ.Расходная.Товары

| ГДЕ Ссылка = &Ссылка

| СГРУППИРОВАТЬ ПО Номенклатура) КАК Док

| ЛЕВОЕ СОЕДИНЕНИЕ

| РегистрНакопления.ОстаткиТоваров.Остатки(,

| Номенклатура В(ВЫБРАТЬ РАЗЛИЧНЫЕ

| Номенклатура

| ИЗ

| Документ.Расходная.Товары

| ГДЕ Ссылка = &Ссылка)) КАК Рег

| ПО

| Док.Номенклатура = Рег.Номенклатура";

Если бы в запросе необходимо было бы получить данные из остатков разных регистров то значение фильтра, а следовательно и наш второй вложенный запрос, повторялся бы во всех параметрах виртуальных таблиц, естественно что система при каждом вложенном запросе заново обращается к базе данных для получения данных.

Временные таблицы

Не помню уже с какого релиза в запросах стало можно использовать временные таблицы. Для этого используется объект «Менеджер временных таблиц». Фактически менеджер временных таблиц описывает пространство имен временных таблиц и отвечает за их создание и уничтожение в базе данных.

Сами временные таблицы действительно физически создаются в базе, соответственно следует относиться к ним осторожно, так как дисковая подсистема на сегодняшний момент самая медленная часть техники, а скорость создания и уничтожения таблиц напрямую от нее зависит.

Перепишем запрос для использования временных таблиц. Во временные таблицы поместим сгруппированную табличную часть документа и список товаров для фильтра виртуальных таблиц:

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

МВТ = Новый МенеджерВременныхТаблиц;

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = МВТ;

Запрос.Текст = "

|ВЫБРАТЬ

| Номенклатура, СУММА(Количество) КАК Количество

|ПОМЕСТИТЬ ДокТЧ

|ИЗ Документ.Расходная.Товары

|ГДЕ Ссылка = &Ссылка

|СГРУППИРОВАТЬ ПО Номенклатура";

Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатЗапроса = Запрос.Выполнить(); //Прим. 1

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = МВТ;

Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ

| Номенклатура

|ПОМЕСТИТЬ СписокТоваров

|ИЗ Документ.Расходная.Товары

|ГДЕ Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Ссылка);

РезультатЗапроса = Запрос.Выполнить(); //Прим. 2

Запрос = Новый Запрос;

Запрос.МенеджерВременныхТаблиц = МВТ;

Запрос.Текст = "

|ВЫБРАТЬ

| Док.Номенклатура,

| Док.Количество КАК Док_Количество,

| ЕСТЬNULL(Рег.КоличествоОстаток,0) КАК Рег_Количество

|ИЗ

| ДокТЧ КАК Док

| ЛЕВОЕ СОЕДИНЕНИЕ

| РегистрНакопления.ОстаткиТоваров.Остатки(,

| Номенклатура В(ВЫБРАТЬ РАЗЛИЧНЫЕ

| Номенклатура

| ИЗ

| СписокТоваров КАК СписокТоваров)) КАК Рег

| ПО

| Док.Номенклатура = Рег.Номенклатура";

РезультатЗапроса = Запрос.Выполнить();

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

//Проверка отрицательных остатков

//Проведение по регистру

КонецЦикла;

КонецПроцедуры

При использовании временных таблиц в тексте запроса применяют инструкцию «Поместить» для создания новой временной таблицы, в этом случае в результат запроса система передает не содержимое этой таблицы (см прим 1 и прим 2 в тексте выше), а количество записей помещенных во временную таблицу, по желанию можно не принимать это значение.

Также допускается использование инструкции «Уничтожить» в этом случае временная таблица уничтожается, в противном случае временные таблицы уничтожаются вместе с объектом менеджер временных таблиц.

В основном нашем запросе я использовал названия временных таблиц как указание на источник получения данных (им обязательно надо назначать синоним, что мы и видим в тексте). Использовать временные таблицы как источник можно не единожды, что при умелом их применении позволит и сократить текст запроса (улучшиться читабельность сложных запросов) и увеличить скорость (при использовании данных временной таблицы в нескольких местах запроса).

Пакетные запросы

Пакетные запросы логично дополняют функционал временных таблиц и дают больше возможностей при работе с запросами.

В пакетном запросе фактически можно описать несколько запросов, как связанных между собой использованием временных таблиц, так и не связанных (можно, но не понятно зачем?). В итоге можно выполнить последовательно все запросы и принять в результате либо массив с результатами исполнения каждого запроса, либо результат последнего. Для получения массива с результатами запроса применяют метод «ВыполнитьПакет()» объекта запрос, а для получения результата последнего запроса «ВыполнитьЗапрос()».

В тексте запроса, запросы пакета разделяются символом «; » (точка с запятой). Область имен виртуальных таблиц у одного пакетного запроса одна. Использование менеджера временных таблиц не требуется, но возможно если вы хотите передать временные таблицы из одного пакетного запроса в другой.

Перепишем процедуру для использования пакетных запросов:

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

Запрос = Новый Запрос;

Запрос.Текст = "

|ВЫБРАТЬ

| Номенклатура, СУММА(Количество) КАК Количество

|ПОМЕСТИТЬ ДокТЧ

|ИЗ Документ.Расходная.Товары

|ГДЕ Ссылка = &Ссылка

|СГРУППИРОВАТЬ ПО Номенклатура

|

|;

|

|ВЫБРАТЬ РАЗЛИЧНЫЕ

| Номенклатура

|ПОМЕСТИТЬ СписокТоваров

|ИЗ Документ.Расходная.Товары

|ГДЕ Ссылка = &Ссылка

|

|;

|

|ВЫБРАТЬ

| Док.Номенклатура,

| Док.Количество КАК Док_Количество,

| ЕСТЬNULL(Рег.КоличествоОстаток,0) КАК Рег_Количество

|ИЗ

| ДокТЧ КАК Док

| ЛЕВОЕ СОЕДИНЕНИЕ

| РегистрНакопления.ОстаткиТоваров.Остатки(,

| Номенклатура В(ВЫБРАТЬ РАЗЛИЧНЫЕ

| Номенклатура

| ИЗ

| СписокТоваров КАК СписокТоваров)) КАК Рег

| ПО

| Док.Номенклатура = Рег.Номенклатура";

Запрос.УстановитьПараметр("Ссылка", Ссылка);

МассивРезультаттов = Запрос.ВыполнитьПакет(); //Прим. 1

РезультатЗапроса = Запрос.Выполнить(); //Прим. 2

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

//Проверка отрицательных остатков

//Проведение по регистру

КонецЦикла;

КонецПроцедуры

Фактически я убрал определение объекта запрос и использование менеджера временных таблиц, объединил тексты запросов (обратите внимание на разделитель «;» между текстами). В результате текст запроса стал читабельнее (а при использовании конструктора запросов намного увеличивается удобство чтения запроса).

После выполнения запроса в переменную «МассивРезультатов» у нас попадет 3 элемента. Первые два будут содержать число характеризующее количество записей помещенных во временные таблицы ДокТЧ и СписокТоваров, а третий будет содержать выборку с полями «Номенклатура», «Док_Количество» и «Рег_Количество».

В переменную «РезультатЗапроса» попадет только выборка.

Ну вот и все что касается пакетных запросов. Очень удобный механизм и с точки зрения написания запросов и с точки зрения чтения сложных запросов.



Другие материалы по теме
Категория: Статьи по 1С | Добавил: GROOVY (06.05.2008) | Автор: Павел Чистов
Просмотров: 19838
Всего комментариев: 13
0  
12 svs1s   (04.10.2011 10:16)
можно ли использовать язык запросов SQL напрямую к Оракл серверу?

0  
13 GROOVY   (04.10.2011 11:18)
Нет.

0  
9 Zari   (01.12.2009 23:47)
Павел, спасибо вам за статью.
И можно вопрос? По поводу скорости выполнения запроса мне показалось, что пакетный запрос по сравнению с вложенными работает не быстрее. Это так или нет?

0  
10 GROOVY   (02.12.2009 00:49)
Тут не в скорости дело. Запрос он и есть запрос. Просто мы можем данные запроса пакета использовать несколько раз. А использую вложенные запросы нам было бы необходимо несколько раз выполнять одинаковый запрос.

0  
11 Zari   (03.12.2009 10:16)
Спасибо. Просто хотелось уточнить этот момент.
А вообще-то, очень удобно, конечно. Еще мне понравилось то, что легко разбить запрос на кусочки и отлаживать кусочками.

0  
8 rasswet   (20.08.2009 12:02)
таблицу значений можно загнать во временную а уж её использовать. но колонки таблицы значений должны быть типизированы перед этим. вроде так...

0  
7 IrinaKostroma   (20.08.2009 11:52)
Может немного не в тему, но давно мучает мысль ,нельзя ли как- нибудь передавать в запрос таблицы значений из отчетов(обработок). Ведь беруться же виртуальные таблицы, таблицы документов и справочников.Почему нельзя передать обычную ТЗ?

0  
6 rasswet   (22.06.2009 09:03)
поясните пожалуйста следующее:
при использование временных таблиц (//Прим. 1 и //Прим. 2) мы сначала группируем Табчасть по номенклатуре и количеству. потом второй ВТ выбираем различные. Вопрос в следующем. если в первой ВТ сгруппировано из ТЧ по номенклатуре, то в ней будет тоже самое что во второй ВТ, так как там выбираются различные, но и в первой ВТ после выполнения тоже будут РАЗЛИЧНЫЕ (с доп полем количество, но это в данном случае не важно)
Зачем нам вторая ВТ если тоже самое уже будет в первое (таже номенкалтура)
или я не понял что-то?

0  
2 Famza   (05.04.2009 21:50)
Ощутил разницу в скорости работы отчета с вложенным запросом и пакетным - пакетный не так шустр. Для большого массива данных пакетник не подошел.
Вопрос: после выполнения пакетного запроса, созданного конструктором, нужно убивать временную таблицу? С помощью Менеджера временных таблиц?

0  
3 GROOVY   (08.05.2009 23:40)
временные таблицы уничтожатся сами при уничтожении менеджера (когда переменная перестанет существовать)

+1  
1 ogorana21   (16.03.2009 01:46)
"Сами временные таблицы действительно физически создаются в базе, соответственно следует относиться к ним осторожно, так как дисковая подсистема на сегодняшний момент самая медленная часть техники, а скорость создания и уничтожения таблиц напрямую от нее зависит."

Временные таблицы сохраняются в базе при выполнении пакетного запроса также, как при выполнении нескольких запросов с созданием Менеджера временных таблиц? То есть меня интересует, есть отличие по скорости при выполнении пакетного запроса и аналогичной серии запросов с использованием Менеджера временных таблиц? (как в приведенном примере)


0  
4 GROOVY   (08.05.2009 23:41)
Отличие есть. Временные таблицы в пакетных запросах формируются только если используется очень большой массив данных.

0  
5 alex_4x   (16.06.2009 10:00)
очень большой массив - это сколько строк ? 1000 , 10000, 100000 ?
Как до выполнения запроса система узнает сколько в запрос попадет строк ?
Временные таблицы - это временно создаваемые таблицы в базе SQL сервера ? тогда, что получается что запрос превращается в хранимую процедуру и регистрируется на сервере, выполняется, а потом из результирующей временной таблицы селектом передается в Сервер1С ? или эту работу по временным таблицам как раз Сервер1С выполняет ?

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
 
 
Форма входа
Login:
Пароль:

Категории раздела
Видеоуроки по 1С [8]
Бесплатные видеоуроки для it-специалистов по работе с системой 1С:Предприятие
Статьи по 1С [8]
Статьи и методические материалы
Утилиты и полезности [5]
Утилиты, обработки и прочие мелочи делающие работу с системой 1С:Предприятие удобнее, да и не только с ней.

Поиск

Наш опрос
Внедряете 8.2?
Всего ответов: 1114

Сейчас на форуме
  • Результаты сдачи экз... (865)
  • Справочник список (3)
  • Задача 1.50 (3)
  • Задача 1.01 (200)
  • Общие вопросы по сда... (108)
  • Задача 2.12 (2)
  • Задача 2.10 (9)
  • Задача 2.8. Не могу... (16)
  • 2.20 (53)
  • 2.16 (2)

  • Поиск

     

    Copyright Павел Чистов © 2012 | Хостинг от uCoz