Дана стаття розрахована на читачів, які знайомі з мовою SQL.

Мова запитів в 1С, що застосовується починаючи з версії 8, сьогодні став корисним інструментом для роботи з базами даних, який дозволяє читати з них, але не записувати. Синтаксично мова запитів дуже схожий з мовою SQL, але російською мовою.

Нижче наведено таблицю відповідності основних операторів мови запитів і SQL:

Оператори мови запитів 1С

оператор SQL

РІЗНІ

З'ЄДНАННЯ

згруповані за

ОБ'ЄДНАТИ

ВПОРЯДКУВАТИ ЗА

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

Виконання запиту 1С з програмного коду здійснюється за допомогою об'єкта вбудованої мови «Запит». Приклад написання запиту до бази даних з використанням вбудованої мови програмування:

Запит \u003d Новий запит; Запрос.Текст \u003d "ВИБРАТИ | Сінонім.Ссилка ЯК Посилання | З | Справочнік.Справочнік1 ЯК Синонім"; Вибірка \u003d Запрос.Виполніть (). Вибрати (); Поки Виборка.Следующій () Цикл // Вставити обробку вибірки ВиборкаДетальниеЗапісі КонецЦікла;

Метод «Виконати» виконує запит, метод «Вибрати» повертає значення типу «ВиборкаІзРезультатаЗапроса». Також можна використовувати метод «вивантажити», який повертає таблицю значень.

Налаштування пошуку зберігаються у властивості «Параметри» (в даному випадку це структура, тому всі методи структури тут застосовні - вставити, видалити і т.д.).

Приклад установки параметра «Запрос.Параметри.Вставіть» ( «Довідник», СправочнікСсилка). У запиті звернутися до параметрів можна через амперсанд «& Довідник». Нижче приклад запиту з використанням параметрів:

Запит \u003d Новий запит; Запрос.Текст \u003d "ВИБРАТИ | Пользователі.Ссилка ЯК Посилання, | Пользователі.Родітель ЯК Батько, | Пользователі.Наіменованіе ЯК Найменування | З | Справочнік.Пользователі ЯК Користувачі | ДЕ | Пользователі.Ссилка \u003d & Довідник"; Запрос.Параметри.Вставіть ( "Довідник", СправочнікСсилка); Вибірка \u003d Запрос.Виполніть (). Вибрати (); Поки Виборка.Следующій () Цикл // Вставити обробку вибірки ВиборкаДетальниеЗапісі КонецЦікла;

Нагадаємо, що мова запитів призначений тільки для читання даних з бази, тому в ньому відсутні аналоги таких операторів SQL, як INS ERT і UPDATE. Дані можна модифікувати тільки через об'єктну модель вбудованої мови програмування 1С. Також в мові запитів 1С існують оператори, аналогів яких немає в SQL, наприклад:

  • У іЄРАРХІЇ
  • помістити
  • індексувати за

У іЄРАРХІЇ - дозволяє вибрати всі елементи ієрархічного довідника, які входять в ієрархію переданої посилання. Приклад запиту з використанням У іЄРАРХІЇ:

ВИБРАТИ Товари.Ссилка, Товари.Артікул З Справочнік.Товари ЯК Товари ДЕ Товари.Ссилка В ІЄРАРХІЇ (& Цитрусові) "

В даному випадку в результат повернуться всі підлеглі елементи довідника номенклатури «Цитрусові», неважливо, скільки рівнів ієрархії є у \u200b\u200bданого довідника.

Також, наприклад, стоїть завдання знайти товар з ім'ям «Ручка». Товар повинен входити в ієрархію «Канц. Товарів », тобто нам не треба шукати дверну ручку. Структура номенклатури в цьому випадку така:

Канцелярія

| _ Ручки пір'яні | _ Ручка червона | _ Ручка синя | _ Ручки чорнильні | _ Лінійки

фурнітура

| _ Ручки дверні | _ Ручка дверна проста | _ Ручка дверна люкс

Пишемо такий запит:

ВИБРАТИ Товари.Ссилка, Товари.Артікул З Справочнік.Товари ЯК Товари ДЕ Товари.Наіменованіе Подібно "Ручка%" І Товари.Ссилка В ІЄРАРХІЇ (& Канцелярія) "

При використанні конструкції У іЄРАРХІЇ необхідно враховувати, що якщо в параметр «Канцелярія» передати порожню посилання, виконання запиту сповільниться, тому що платформа буде перевіряти кожен елемент на приналежність корені.

помістити - Даний оператор поміщає результат в тимчасову таблицю. Приклад запиту:

ВИБРАТИ Пользователі.Ссилка ЯК Посилання, Пользователі.Родітель ЯК Батько, Пользователі.Наіменованіе ЯК Найменування помістити ОтобранниеПользователі З Справочнік.Пользователі ЯК Користувачі ДЕ Пользователі.Ссилка \u003d & Довідник; ВИБРАТИ ОтобранниеПользователі.Ссилка ЯК Посилання, ОтобранниеПользователі.Родітель ЯК Батько, ОтобранниеПользователі.Наіменованіе ЯК Найменування ІЗ ОтобранниеПользователі ЯК ОтобранниеПользователі

Даний запит на SQL буде виконаний декількома запитами:

  • Створення тимчасової таблиці (платформа вміє «перевикористати» раніше створені тимчасові таблиці, тому створення відбувається не завжди);
  • Приміщення даних в тимчасову таблицю;
  • Виконання основного запиту, а саме SEL ECT з цієї тимчасової таблиці;
  • Знищення / очищення тимчасової таблиці.

Тимчасова таблиця може бути знищена явно, через конструкцію ЗНИЩИТИ, Або неявно - при закритті менеджера тимчасових таблиць.

У об'єкта «Запит» вбудованої мови програмування є властивість «МенеджерВременнихТабліц», яке призначене для роботи з тимчасовими таблицями. Приклад коду:

МВТ \u003d Новий МенеджерВременнихТабліц (); Запит \u003d Новий запит; Запрос.МенеджерВременнихТабліц \u003d МВТ;

Після виконання запиту змінну МВТ можна використовувати вдруге в іншому запиті, що, безсумнівно, є ще одним плюсом використання тимчасових таблиць. В даному випадку тимчасова таблиця з бази буде видалена при виклику методу «Закрити» ...

МВТ.Закрить ();

... або ж при очищенні змінної з пам'яті, тобто при виконанні методу, в якому змінна була оголошена. Тимчасові таблиці підвищують навантаження на дискову підсистему, тому не слід створювати дуже багато тимчасових підсистем (в циклі, наприклад), або підсистем великого об'єму.

індексувати за - цей оператор застосовується спільно з оператором Помістити. При створенні тимчасової таблиці цим оператором можна проіндексувати створювану таблицю, що істотно прискорює роботу з нею (але тільки, якщо індекс підходить під ваш запит).

Безкоштовна консультація експерта

Дякуємо за Ваше звернення!

Спеціаліст 1С зв'яжеться з вами протягом 15 хвилин.

Особливості деяких операторів мови запитів

ДЛЯ ЗМІНИ - даний оператор призначений для блокування певної таблиці запиту (або всіх таблиць, які беруть участь в запиті). Блокування здійснюється накладенням U блокування на таблицю. На SQL це реалізується через hint UPDLOCK. Дана конструкція необхідна для запобігання блокувань типу deadlock. Приклад запиту з конструкцією ДЛЯ ЗМІНИ:

ВИБРАТИ Пользователі.Ссилка ЯК Посилання, Пользователі.Родітель ЯК Батько, Пользователі.Наіменованіе ЯК Найменування ІЗ Справочнік.Пользователі ЯК Користувачі ЛІВЕ З'ЄДНАННЯ Справочнік.РФК ЯК РФК ПО Пользователі.РФК \u003d РФК.Ссилка ДЛЯ ЗМІНИ Справочнік.Пользователі

В даному прикладі U блокування буде встановлена \u200b\u200bна таблицю «Користувачі». Якщо не вказувати таблицю для блокування, вона буде накладена на всі таблиці, які беруть участь в запиті. Важливо відзначити, що дана конструкція працює тільки в конфігураціях, в яких включений автоматичний режим управління блокуваннями.



З'ЄДНАННЯ - запит підтримує з'єднання ЛІВЕ / ПРАВОЕ, ПОВНЕ, ВНУТРІШНЄ,що відповідає з'єднанням в SQL - LEFT / RIGHT JOIN, OUTER JOIN, INNER JOIN.

Однак при використанні конструктора запитів ви не зможете зробити ПРАВОЕ З'ЄДНАННЯ.Конструктор просто буде міняти місцями таблиці, але оператор буде завжди лівий. З цієї причини в 1С ніколи не зустрінеш застосування правого з'єднання.

Синтаксично з'єднання виглядає так:

ВИБРАТИ Табліца1.Ссилка ЯК Посилання ІЗ Справочнік.Справочнік1 ЯК Таблица1 ЛІВЕ З'ЄДНАННЯ Справочнік.Справочнік2 ЯК Таблица2 ПО Табліца1.Реквізіт \u003d Табліца2.Реквізіт

У мові запитів 1С відсутня оператор для з'єднання декартова твори (CROSS JOIN). Однак відсутність оператора не означає, що мова запитів не підтримує такого з'єднання. З'єднати таблиці при необхідності можна таким чином:

ВИБРАТИ Табліца1.Ссилка ЯК Посилання ІЗ Справочнік.Справочнік1 ЯК Таблица1 ЛІВЕ З'ЄДНАННЯ Справочнік.Справочнік2 ЯК Таблица2 ПО ІСТИНА

Як видно з прикладу, заданий ключ з'єднання ПО ІСТИНА, Тобто кожен рядок однієї таблиці відповідає рядку інший. Тип з'єднання (ЛІВЕ, ПРАВОЕ, ПОВНЕ, ВНУТРІШНЄ) не важливий, якщо у вас є рядки в обох таблицях, але якщо в якійсь із таблиць немає рядків (пускаючи таблиця) - результат буде відрізнятися. Наприклад, при використанні ВНУТРІШНЄ з'єднання результат буде порожній. При використанні ЛІВЕ / ПРАВОЕ з'єднання в результаті буде чи не буде даних в залежності від того, до якої таблиці ми приєднуємося - з даними чи ні. При використанні ПОВНОГО з'єднання дані будуть завжди (природно, тільки однієї таблиці, так як в інший порожнеча), вибір типу з'єднання залежить від конкретної прикладної задачі.

Невелика візуальна підказка, як працюють різні типи з'єднань:



ПОДІБНО.На відміну від аналогічного оператора мови SQL - LIKE, шаблон для ПОДІБНО можна задати, використовуючи тільки деякі спец символи:

  • % (Відсоток): послідовність, що містить будь-яку кількість довільних символів;
  • _ (Підкреслення): один довільний символ;
  • / - наступний символ потрібно інтерпретувати як звичайний символ.

ПІДСУМКИ ПОаналогом на SQL можна назвати оператор ROLLUP. Приклад використання оператора ПІДСУМКИ:

ВИБРАТИ Товари.Цена ЯК Ціна, Товари.Товар ЯК Товар ІЗ Справочнік.Номенклатура ЯК Товари ПІДСУМКИ СЕРЕДНЯ (Ціна) ПО Товар

Результат буде такий:

ліжко

9833,333

праска

ручка

Тобто в результат додається додатковий рядок, що містить значення поля, по якому проводиться групування і значення агрегує функції.

Робота з пакетними запитами

1С дозволяє працювати з пакетами запитів. У пакетному запиті тексти запитів розділяються крапкою з комою (;). Виконання пакетного запиту 1С здійснюється послідовно. Приклад тексту пакетного запиту:

ВИБРАТИ Пользователі.Ссилка ЯК Посилання, Пользователі.Родітель ЯК Батько, Пользователі.Наіменованіе ЯК Найменування ІЗ Справочнік.Пользователі ЯК Користувачі;
ВИБРАТИ ГрафікРаботи.Пользователь ЯК Користувач, ГрафікРаботи.Дата ЯК Дата, ГрафікРаботи.РабочіхЧасов ЯК РабочіхЧасов З РегістрСведеній.ГрафікРаботи ЯК ГрафікРаботи

Для отримання результату всіх запитів, що входять в пакет, необхідно скористатися методом об'єкта запиту «ВиполнітьПакет», замість «Виконати». Даний метод послідовно виконує всі запити. Результат запиту - масив результатів для кожного запиту з пакета, а послідовність розташування в масиві така ж, як послідовність запитів в тексті пакета.

Розглядаючи мову запитів, варто згадати про таку особливість, як віртуальні таблиці. Віртуальні таблиці відсутні в базі даних, це своєрідна обгортка, яка виконується на стороні СУБД як запит з використанням підзапитів. Приклад запиту 1С з використанням віртуальних таблиць:

ВИБРАТИ РегістрОбязательствОбороти.Обязательство ЯК Зобов'язання З РегістрНакопленія.РегістрОбязательств.Обороти () ЯК РегістрОбязательствОбороти

Такий запит на СУБД буде виглядати так:

SEL ECT T1.Fld25931RRef FR OM (SELECT T2._Fld25931RRef AS Fld25931RRef, CAST (SUM (T2._Fld25936) AS NUMERIC (38, 8)) AS Fld25936Turnover_, CAST (SUM (T2._Fld25937) AS NUMERIC (38, 8)) AS Fld25937Turnover_ FR OM dbo._AccumRgTn25938 T2 WH ERE ((T2._Fld949 \u003d @ P1)) AND ((T2._Fld25936 @ P2 OR T2._Fld25937 @ P3)) GROUP BY T2._Fld25931RRef HAVING (CAST (SUM (T2._Fld25936 ) AS NUMERIC (38, 8))) 0.0 OR (CAST (SUM (T2._Fld25937) AS NUMERIC (38, 8))) 0.0) T1 \u003e\u003e\u003e\u003e

Видно, що не схоже на SQL, оскільки є підзапит, угруповання. Віртуальні таблиці, за великим рахунком - це «синтаксичний цукор», тобто створені, в общем-то, для зручності розробки запитів, щоб запити були компактніше і читабельнее.

Віртуальні таблиці є тільки у регістрів, але які саме віртуальні таблиці доступні у регістру, можна побачити в конструкторі запитів.



При використанні віртуальних таблиць необхідно завжди давати умова відбору. В іншому випадку можуть виникнути проблеми з продуктивністю.



У тексті запиту це виглядає так:

РегістрНакопленія.РегістрОбязательств.Обороти (, Операція \u003d & Операція) ЯК РегістрОбязательствОбороти

Для зручності написання запитів, тобто створення текстів запитів, в 1С існує конструктор, який можна викликати через контекстне меню (правою кнопкою миші):



У конструкторі запитів можна побачити повний список підтримуваних функцій і операторів мови запитів.


Конструктор запитів є дуже гнучким візуальним інструментом для створення запитів будь-якої складності. Він доступний тільки в режимі конфігуратора. У режимі Підприємства є так звана «Консоль запитів» - це зовнішня обробка, яку поставляють на диску ІТС. Для керованого застосування консоль запитів можна скачати на сайті its.1c.ru.

Опис роботи в конструкторі запитів виходить за рамки тематики даної статті, тому детально розглядатися не буде.

Причини неоптимальною роботи запитів

Нижче наведено список основних причин (але не всіх), які призводять до уповільнення виконання запиту.

  • Використання з'єднання з підзапитах

Не рекомендується виконувати з'єднання з підзапитах, підзапити необхідно замінити тимчасовими таблицями. З'єднання підзапитів може призводити до значної втрати в продуктивності, при цьому виконання запиту на різних СУБД може значно відрізнятися в швидкості. Швидкість виконання таких запитів також чутлива до статистики в СУБД. Причина такої поведінки в тому, що оптимізатор СУБД не завжди коректно може визначити оптимальний план виконання запитів, так як оптимізатор нічого не знає про те, яка кількість рядків поверне підзапит після свого виконання.

  • Використання віртуальних таблиць в з'єднаннях запиту

Віртуальні таблиці на рівні СУБД виконуються як підзапити, тому причини такі ж, як в першому пункті.

  • Використання умов в запиті, невідповідних під існуючі індекси

Якщо в умовах запиту (в операторі ДЕ або в умовах віртуальної таблиці) використовуються поля, які не всі входять в індекс, даний запит буде виконаний з використанням SQL конструкції table scan або index scan (повністю або частково). Це позначиться не тільки на часі виконання запиту, але також буде накладена надлишкова S блокування на зайві рядки, що в свою чергу може привести до ескалації блокувань, тобто буде заблокована вся таблиця.

  • Використання АБО в условиях запроса

Використання логічного оператора АБО в конструкції ДЕ може також призводити до сканування таблиці (table scan). Це відбувається через те, що СУБД не може коректно використовувати індекс. замість АБОможна застосувати конструкцію ОБ'ЄДНАТИ ВСІ.

  • Отримання даних через точку для полів складеного типу

Не рекомендується отримувати значення через точку (в конструкції ВИБРАТИ, ДЕ), Оскільки якщо реквізит об'єкта виявиться складовим типом, з'єднання буде відбуватися з кожної таблицею, що входить в цей складовою тип. В результаті запит на СУБД буде значно ускладнений, це може перешкодити оптимізатора у виборі коректного плану виконання запиту.

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

У пакетному запиті фактично можна описати кілька запитів, як пов'язаних між собою використанням тимчасових таблиць, так і не пов'язаних (можна, але не зрозуміло навіщо?). У підсумку можна виконати послідовно всі запити і прийняти в результаті яких масив з результатами виконання кожного запиту, або результат останнього. Для отримання масиву з результатами запиту застосовують метод ВиполнітьПакет () об'єкта запит, а для отримання результату останнього запиту Виконати запит().

У тексті запиту, запити пакета поділяються символом «;» (крапка з комою). Область імен віртуальних таблиць у одного пакетного запиту одна. Використання менеджера тимчасових таблиць не потрібно, але можливо якщо ви хочете передати тимчасові таблиці з одного пакетного запиту в інший.
Код 1C v 8.х Процедура ОбработкаПроведенія (Відмова, РежімПроведенія)

Запит \u003d Новий запит;
Запрос.Текст \u003d "
| ВИБРАТИ
| Номенклатура, СУМА (Кількість) ЯК Кількість
| Помістити ДокТЧ
| З
| ДЕ
| Посилання \u003d & Посилання
| Згруповані за Номенклатура
|;
| ВИБРАТИ РІЗНІ
| номенклатура
| Помістити СпісокТоваров
| З
| Документ.Расходная.Товари
| ДЕ
| Посилання \u003d & Посилання
|;
| ВИБРАТИ
| Док.Номенклатура,
| Док.Колічество ЯК Док_Колічество,
| ЕСТЬNULL (Рег.КолічествоОстаток, 0) ЯК Рег_Колічество
| З
| ДокТЧ ЯК Док
| ЛІВЕ З'ЄДНАННЯ
| РегістрНакопленія.ОстаткіТоваров.Остаткі (,
| Номенклатура В (ВИБРАТИ РІЗНІ
| номенклатура
| З
| СпісокТоваров ЯК СпісокТоваров)) ЯК Реєстр
| ПО
| Док.Номенклатура \u003d Рег.Номенклатура ";

Поки Виборка.Следующій () Цикл
// Перевірка негативних залишків
// Проведення по регістру
КонецЦікла;
КонецПроцедури

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

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

У змінну РезультатЗапроса потрапить тільки вибірка.

Ну ось і все що стосується пакетних запитів. Дуже зручний механізм і з точки зору написання запитів і з точки зору читання складних запитів.

Інформація взята з сайту

У статті розповідається про механізм пакетних запитів, реалізованих в платформі «1С: Підприємство». Прочитавши статтю, ви дізнаєтеся:

  • Що таке пакетні запити і для чого вони потрібні?
  • Як створити пакет запитів за допомогою конструктора запитів?
  • Як повернути масив результатів для кожного запиту з пакету?

застосовність

Матеріал актуальний для поточних версій платформи «1С: Підприємство» редакції 8.3

Призначення пакету запитів

Платформа дозволяє працювати з пакетами запитів. Отримуємо можливість виконати кілька запитів «за раз». У пакетному запиті тексти запитів поділяються символом «;» (крапка з комою).

Запити виконуються послідовно, при цьому тимчасові таблиці, які були створені під час виконання будь-якого запиту, будуть існувати до закінчення виконання всього пакету запиту або до виконання в пакеті запиту, що знищує цю тимчасову таблицю. Важлива відмінність від вкладеного запиту полягає в тому, що доступні результати кожного запиту пакета окремо.

Пакети запитів дозволяють досягти поетапного виконання запиту. Для цього в пакетному запиті спочатку відбувається створення тимчасових таблиць, далі - їх спільне використання (з'єднання, об'єднання, фільтри) для отримання підсумкового результату запиту. Також важливо відзначити, що використання тимчасових таблиць в пакетних запитах дозволяє поліпшити читаність тексту запиту.

Об'ємні запити з загорнутими один в одного вкладеними запитами найчастіше бувають досить складними для сприйняття. Але якщо переписати такий запит з використанням тимчасових таблиць, наочність запиту може підвищитися досить сильно. Застосування пакета запитів з тимчасовими таблицями також може підвищити продуктивність запиту.

Існують методики оптимізації продуктивності запитів, засновані на заміні вкладених запитів на тимчасові таблиці.

Тимчасова таблиця може бути корисна, коли необхідно використовувати одні і ті ж дані в великому запиті кілька разів, наприклад, поєднуючи або об'єднуючи з іншими таблицями. При використанні вкладених запитів такі дані довелося б отримувати кілька разів за допомогою однакових вкладених запитів, що, безумовно, позначилося б і на читання тексту, і на продуктивності.

Створення пакету запитів за допомогою конструктора

Окремі запити, що входять в пакет, відокремлюються в тексті символом «;» (крапка з комою). Щоб не розділяти текст запиту вручну, можна використовувати для цього конструктор запитів.
У конструкторі запитів є окрема закладка для пакетів запитів. Запити в пакет можна додавати за допомогою відповідної кнопки на командній панелі, а також пересувати вгору або вниз.

Візуальне відображення окремих запитів - закладки в правій частині конструктора, за допомогою яких можна перейти до редагування тексту окремого запиту. На цих закладках для тимчасових таблиць виводяться імена, для запитів на вибірку даних - «Запит пакета 2» і т.п., на знищення - «- ІмяВТ».

Також в списку таблиць бази даних з'являються тимчасові таблиці, створені в рамках даного пакету. Однак це не означає, що тимчасові таблиці зберігаються в базі даних разом з усіма іншими таблицями інформаційної бази.

Виконання запитів пакета

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

У тексті пакетного запиту можливе використання і знищення тимчасових таблиць, які існували в установленому менеджері тимчасових таблиць на момент запуску пакета на виконання.

Крім методу Виконати (), Послідовно виконує всі запити пакета і повертає результат останнього запиту в пакеті, в платформі існує ще один метод - ВиполнітьПакет ().

Цей метод послідовно виконує всі запити і повертає масив результатів для кожного запиту з пакету в послідовності розташування запитів в тексті пакета.

Результатом виконання запиту на знищення тимчасової таблиці є значення Не визначене, Яке також міститься в масив результатів.

Коли мій запит став таким складним, що перевищив межі мого розуміння, я вирішив використовувати пакетні запити.

Але зіткнувся з фактом, що нічого про них не знаю. Виявилося, все дуже просто. Через 5 хвилин ви будете вміти користуватися пакетними запитами. Починайте читати.

Як виявилося все дуже просто. Потрібно просто написати кілька запитів, між якими ставиться крапка з комою. Результат повернеться в останньому запиті.

Пакетні запити з'явилися тільки в версії 8.1.11.67.4.

Ось текст запиту:

ВИБРАТИ Т1.Зн помістити ВТБукви ІЗ (ВИБРАТИ "А" ЯК Зн ОБ'ЄДНАТИ ВСІ ВИБРАТИ "Б") ЯК Т1;

ВИБРАТИ Т1.Зн помістити ВТЦіфри ІЗ (ВИБРАТИ "1" ЯК Зн ОБ'ЄДНАТИ ВСІ ВИБРАТИ "2") ЯК Т1;

ВИБРАТИ ТБ.Зн, ТЦ.Зн, ТБ.Зн + ТЦ.Зн З ВТБукви ЯК ТБ, ВТЦіфри ЯК ТЦ

Пакетні запити підтримуються в будь-якої звичайної консолі запитів.

На малюнку представлений зразок виконання запиту:

А тепер трохи з досвіду. Навіщо потрібні пакетні запити.

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

Раніше, коли не було тимчасових таблиць, довелося б дублювати текст запиту.

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

Крім того, якщо використовується система компонування даних (СКД), вона грамотно відбирає потрібні поля і мінімізує весь пакет запитів.

Якщо у запитів був метод Запрос.Виполніть () то тепер з'явився метод Запрос.ВиполнітьПакет (), Який повертає всі таблиці з пакета, у вигляді масиву.

Анонс пакетних запитів на сайті 1с знаходиться тут: http://v8.1c.ru/overview/release_8_1_11/#Functional

Історія з життя

Поясню, що мене спонукало на пакетні запити.

Значить, уявіть є документ, у нього таблична частина. У колонці « Помилка»Ознака, чи є помилка при заповненні документа. У колонці « ТекстОшібкі»Може бути одне або декілька пропозицій з текстами помилок. Види помилок, що містяться в пропозиціях відомі заздалегідь.

Так ось, ми заносимо список всіх помилок в таблицю КодиОшібок - там міститься код помилки і подстрока пошуку.

Отримуємо для кожного рядка одну, дві або більше помилок. Оскільки в одному рядку може бути кілька помилок.

Але помилка може бути і не розпізнано, тобто прапор « Помилка»Коштує, а текст помилки не видав нам код помилки.

Робимо ліве з'єднання, там де код помилки є NULL, даємо код помилки « Інші помилки» .

Але проблема була в тому, що кодів помилок було близько 200, тому ліве з'єднання працювало дуже довго. Довелося замінити його на внутрішнє з'єднання, яке літало. Але при цьому губилися рядки, для яких помилка була не знайдено. Я так і не зміг зрозуміти, як витягти ці рядки в результат.

Запит писався для системи компоновки, тобто ніяких таблиць значень або тимчасових таблиць застосовувати не можна в принципі. Тут і стали в нагоді пакетні запити.

Я просто ще раз з'єднав всі рядки з помилками з усіма рядками, для яких були знайдені помилки, і додав все-таки вид помилки «Інші помилки».

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

Структура конфігурації представлена \u200b\u200bна малюнку.

(16.22 кілобайт) Кількість скачувань: 64

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

Запит \u003d Новий запит;
Запрос.Текст \u003d "
| ВИБРАТИ
| Док.Номенклатура,
| СУМА (Док.Колічество) ЯК Док_Колічество,
| МІНІМУМ (ЕСТЬNULL (Рег.КолічествоОстаток, 0)) ЯК Рег_Колічество
| З
| Документ.Расходная.Товари ЯК Док
| ЛІВЕ З'ЄДНАННЯ
| РегістрНакопленія.ОстаткіТоваров.Остаткі () ЯК Реєстр
| ПО
| Док.Номенклатура \u003d Рег.Номенклатура
| ДЕ
| Посилання \u003d & Посилання
| Згруповані за Док.Номенклатура ";

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

КонецЦікла;

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

Природно приведений запит абсолютно не оптимальний. За допомогою вкладених запитів оптимізуємо його: Зробимо групування табличній частині документа до з'єднання з таблицею залишків, в параметри віртуальної таблиці передамо список товарів як значення умови для розрахунку залишків. У підсумку наш запит прийме наступний вигляд:

| ВИБРАТИ
| Док.Номенклатура,

| З
| (ВИБРАТИ

| З
| Документ.Расходная.Товари
| ДЕ
| Посилання \u003d & Посилання
| Згруповані за Номенклатура) ЯК Док
| ЛІВЕ З'ЄДНАННЯ
номенклатура В
| (ВИБРАТИ РІЗНІ
| номенклатура
| З
| Документ.Расходная.Товари
| ДЕ
| Посилання \u003d & Посилання)) ЯК Реєстр
| ПО

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

тимчасові таблиці

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

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

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

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

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

Запит \u003d Новий запит;
Запрос.Текст \u003d "
| ВИБРАТИ
| Номенклатура, СУМА (Кількість) ЯК Кількість
| Помістити ДокТЧ
| З
| Документ.Расходная.Товари
| ДЕ
| Посилання \u003d & Посилання
| Згруповані за Номенклатура ";

Запит \u003d Новий запит;
Запрос.МенеджерВременнихТабліц \u003d МВТ;
Запрос.Текст \u003d "ВИБРАТИ РІЗНІ
| номенклатура
| Помістити СпісокТоваров
| З
| Документ.Расходная.Товари
| ДЕ
| Посилання \u003d & Посилання ";

Запит \u003d Новий запит;
Запрос.МенеджерВременнихТабліц \u003d МВТ;
Запрос.Текст \u003d "
| ВИБРАТИ
| Док.Номенклатура,
| Док.Колічество ЯК Док_Колічество,
| ЕСТЬNULL (Рег.КолічествоОстаток, 0) ЯК Рег_Колічество
| З
| ДокТЧ ЯК Док
| ЛІВЕ З'ЄДНАННЯ
| РегістрНакопленія.ОстаткіТоваров.Остаткі (,
| номенклатура
| З
| ПО
| Док.Номенклатура \u003d Рег.Номенклатура ";

РезультатЗапроса \u003d Запрос.Виполніть ();
Вибірка \u003d РезультатЗапроса.Вибрать ();

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

// Перевірка негативних залишків

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

КонецЦікла;

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

При використанні тимчасових таблиць в тексті запиту застосовують інструкцію Помістити для створення нової тимчасової таблиці, в цьому випадку в результат запиту система передає не вміст цієї таблиці (див прим 1 і прим 2 в тексті вище), а кількість записів поміщених в тимчасову таблицю, за бажанням можна не брати це значення.

Також допускається використання інструкції знищити в цьому випадку тимчасова таблиця знищується, в іншому випадку тимчасові таблиці знищуються разом з об'єктом менеджер тимчасових таблиць.

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

пакетні запити

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

У пакетному запиті фактично можна описати кілька запитів, як пов'язаних між собою використанням тимчасових таблиць, так і не пов'язаних (можна, але не зрозуміло навіщо?). У підсумку можна виконати послідовно всі запити і прийняти в результаті яких масив з результатами виконання кожного запиту, або результат останнього. Для отримання масиву з результатами запиту застосовують метод ВиполнітьПакет () об'єкта запит, а для отримання результату останнього запиту Виконати запит().

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

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

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

Запит \u003d Новий запит;
Запрос.Текст \u003d "
| ВИБРАТИ
| Номенклатура, СУМА (Кількість) ЯК Кількість
| Помістити ДокТЧ
| З
| Документ.Расходная.Товари
| ДЕ
| Посилання \u003d & Посилання
| Згруповані за Номенклатура
|;
| ВИБРАТИ РІЗНІ
| номенклатура
| Помістити СпісокТоваров
| З
| Документ.Расходная.Товари
| ДЕ
| Посилання \u003d & Посилання
|;
| ВИБРАТИ
| Док.Номенклатура,
| Док.Колічество ЯК Док_Колічество,
| ЕСТЬNULL (Рег.КолічествоОстаток, 0) ЯК Рег_Колічество
| З
| ДокТЧ ЯК Док
| ЛІВЕ З'ЄДНАННЯ
| РегістрНакопленія.ОстаткіТоваров.Остаткі (,
| Номенклатура В (ВИБРАТИ РІЗНІ
| номенклатура
| З
| СпісокТоваров ЯК СпісокТоваров)) ЯК Реєстр
| ПО
| Док.Номенклатура \u003d Рег.Номенклатура ";

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

// Перевірка негативних залишків

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

КонецЦікла;

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

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

Після виконання запиту в змінну МассівРезультатов у нас потрапить 3 елементи. Перші два будуть містити число характеризує кількість записів поміщених в тимчасові таблиці ДокТЧ і Список товарів, А третій буде містити вибірку з полями номенклатура, Док_ кількість і Рег_ кількість.

У змінну РезультатЗапроса потрапить тільки вибірка.

Ну ось і все що стосується пакетних запитів. Дуже зручний механізм і з точки зору написання запитів і з точки зору читання складних запитів.