Немного о менеджерах… Временных таблиц

angry_manager

Всем приветsmiley.

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

Менеджер временных таблиц (свойство объекта Запрос) – это объект встроенного языка, предназначенный для управления временными таблицами. Менеджер временных таблиц хранит в себе данные временных таблиц. Как с ним работать? Сейчас разберемсяsmiley.

Экземпляр менеджера временных таблиц создается так:

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

Все временные таблицы, созданные в экземпляре менеджера, существуют до тех пор, пока существует сам экземпляр менеджера временных таблиц.

Задача 1: Понять в какой момент времени менеджер начинает хранить в себе данные временных таблиц.

Для примера создадим самый элементарный запрос с одной временной таблицей с помощью конструктора запроса (с обработкой результата) и определим менеджер временных таблиц:

Запрос = Новый Запрос;
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.Текст = 
	"ВЫБРАТЬ
	|	Валюты.Ссылка
	|ПОМЕСТИТЬ ВТ_Валюты	
	|ИЗ
	|	Справочник.Валюты КАК Валюты";

РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
	// Вставить обработку выборки ВыборкаДетальныеЗаписи
КонецЦикла;

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

Теперь посмотрите содержимое менеджера временных таблиц в отладке.

Это можно сделать с помощью свойства Таблицы (тип ВременныеТаблицыЗапроса) менеджера временных таблиц. Для того, чтобы увидеть количество элементов данной таблицы, необходимо воспользоваться методом Количество():

МенеджерВременныхТаблиц.Таблицы.Количество()

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

Теперь поставьте точку останова на строке: ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

Теперь вновь посмотрите содержимое менеджера временных таблиц. Что теперь? Теперь вот это:

tablo_manager

Надеюсь, здесь Вам все понятноsmiley?

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

Сделаем этоwink!

Задача 2:  Получить данные из менеджера временных таблиц в другом запросе.

Немного модифицируем наш код:

Запрос = Новый Запрос;
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.Текст = 
	"ВЫБРАТЬ
	|	Валюты.Ссылка
	|ПОМЕСТИТЬ ВТ_Валюты
	|ИЗ
	|	Справочник.Валюты КАК Валюты";

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

Запрос2 = Новый Запрос;
Запрос2.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос2.Текст =

Текст нового запроса (Запрос2) напишем с помощью конструктора запроса (правая кнопка мыши — пункт меню «Конструктор запроса»). В открывшемся конструкторе запроса посмотрим на закладку «Таблицы и поля». В секции «База данных» вы не найдете нашу временную таблицу (ВТ_Валюты) т.к. по-сути, временная таблица была создана «в другом пространстве». Для того, чтобы «новое пространство» узнало о существовании таблицы в менеджере, необходимо создать описание этой временной таблицы. Для описания временной таблицы в конструкторе есть кнопка:

create_description_vt

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

structure_vt

Все просто и очевидноsmiley.

Определяем наши выходные поля:

result_vt

Далее обойдем результат выборки:

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

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

Запрос.Текст = 
	"ВЫБРАТЬ
	|	Валюты.Ссылка
	|ПОМЕСТИТЬ ВТ_Валюты
	|ИЗ
	|	Справочник.Валюты КАК Валюты";

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

Запрос2 = Новый Запрос;
Запрос2.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос2.Текст = 
	"ВЫБРАТЬ
	|	ВТ_Валюты.Ссылка,
	|	ВТ_Валюты.Ссылка.Код КАК Код
	|ИЗ
	|	ВТ_Валюты КАК ВТ_Валюты";

РезультатЗапроса = Запрос2.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
	Сообщить(Выборка.Код);
КонецЦикла;

Все работает! Данные успешно получены и обработаныyes.

Задача 3: Уничтожить временные таблицы менеджера.

Это можно сделать двумя способами.

1 способ: У менеджера существует метод Закрыть(), который уничтожает все таблицы, находящиеся в менеджере.

РезультатЗапроса = Запрос2.Выполнить();
МенеджерВременныхТаблиц.Закрыть();

2 способ: Ключевое слово УНИЧТОЖИТЬ (удаление какой-то одной конкретной таблицы).

Запрос2.Текст = "УНИЧТОЖИТЬ ВТ_Валюты";
РезультатЗапроса = Запрос2.Выполнить();

А теперь вы можете задать вопрос: А надо ли вообще уничтожать временные таблицы? Вопрос хороший. Ответ: зависит от способа создания временной таблицы и от возможных проблем с нехваткой памятью. Разберем более подробно.

Пример 1: Временная таблица была создана без указания менеджера временных таблиц.

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
                |	ВТ_Валюты.Ссылка,
                |	ВТ_Валюты.Ссылка.Код КАК Код
                |ПОМЕСТИТЬ ВТ_Валюты
                |ИЗ
                |	ВТ_Валюты КАК ВТ_Валюты";

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

Пример 2: Временная таблица была создана с указанием менеджера временных таблиц.

Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц; 
Запрос.Текст = "ВЫБРАТЬ
                |	ВТ_Валюты.Ссылка,
                |	ВТ_Валюты.Ссылка.Код КАК Код
                |ПОМЕСТИТЬ ВТ_Валюты
                |ИЗ
                |	ВТ_Валюты КАК ВТ_Валюты";

Здесь все наоборот. Т.к. мы в явном виде указали менеджер временных таблиц, то система не будет принудительно очищать его содержимое после выполнения запроса т.к. вдруг мы планируем данный менеджер передать в другую процедуру/функцию. Именно поэтому, как только отпала необходимость во временных таблицах, необходимости очищать менеджер с помощью метода Закрыть() т.к. иначе временные таблицы будут висеть в памяти сервера СУБД до тех пор, пока процедура/функция не закончит работу.

Если, например, в менеджере хранится 10 временных таблиц, а в дальнейшем будет использована только 1 временная таблица, то оставшиеся 9 временных таблиц желательно удалять с помощью ключевого слова УНИЧТОЖИТЬ.

Пример 3: Есть какой-то большой запрос с кучей временных таблиц, который при выполнении приводит к проблемам нехватки памяти.

Например, в запросе 25 временных таблиц. Первая временная таблица (ВТ1) нужна только лишь для того, чтобы сформировать вторую временную (ВТ2) таблицу. Вторая временная таблица нужна только лишь для того, чтобы сформировать третью временную таблицу. Для формирования оставшихся 23 временных таблиц данные первой и второй временной таблицы уже не нужны. Т.к. больше таблицы ВТ1 И ВТ2 не нужны, то с целью оптимизации их можно УНИЧТОЖИТЬ, чтобы не занимали место в памяти.

Для наглядности:

ВТ1 — первая временная таблица

ВТ2 — сформирована по данным таблицы ВТ1

ИМЕННО В ЭТОТ МОМЕНТ НУЖНО УНИЧТОЖИТЬ ВРЕМЕННУЮ ТАБЛИЦУ ВТ1

ВТ3 — сформирована по данным таблицы ВТ2

ИМЕННО В ЭТОТ МОМЕНТ НУЖНО УНИЧТОЖИТЬ ВРЕМЕННУЮ ТАБЛИЦУ ВТ2

…остальной текст запроса…

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

Задача 4: Научиться просматривать содержимое временных таблиц менеджера в отладчике.

Вы можете спросить: А зачем это нужно? Ведь это всегда можно сделать в консоли запросов! Соглашусь, но порой запросы бывают очень большие и  с огромным числом параметров. Заполнение данных параметров в консоли запросов – дело не из приятных, а порой и очень долгих. Ладно, не буду философствоватьlaugh.  Если нам нужно просмотреть содержимое временной таблицы в отладке, то необходимо написать такую функцию и ее вызывать в отладке:

Функция СодержимоеВременнойТаблицы(Запрос, ИмяВременнойТаблицы)
	ЗапросВТ = Новый Запрос ("ВЫБРАТЬ * ИЗ " + ИмяВременнойТаблицы);
	ЗапросВТ.МенеджерВременныхТаблиц = Запрос.МенеджерВременныхТаблиц;
	Возврат ЗапросВТ.Выполнить().Выгрузить();
КонецФункции

Например:

scan_vt

На этом все! Надеюсь, Вам было интересно и познавательноwinklaughcool.

Понравилось? Не забудь поддержать сайт!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *