← вся теориятеория к собесу · Язык запросов 1С

Язык запросов 1С: основы и параметры

разбор писал Даниил, автор Сеньорчика

Зачем это спрашивают

Язык запросов 1С похож на SQL, но читает объекты конфигурации, а не таблицы базы, и пишется по-русски. На собесе по основам спрашивают про параметры, порядок ключевых слов после ВЫБРАТЬ, ПЕРВЫЕ без сортировки и иерархию. Результаты запросов ниже сверены тем же запросом на PostgreSQL.

// Так спрашивают: «Зачем параметры, если можно подставить значение в текст?» «Что вернёт ПЕРВЫЕ 1 без УПОРЯДОЧИТЬ ПО?» «Как отобрать группу справочника вместе с подгруппами?» «Как сравнить строку неограниченной длины?»

Параметры

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

Перечисления и предопределённые элементы пишут прямо в тексте через ЗНАЧЕНИЕ(...): это константа конфигурации, а не пользовательские данные. Неустановленный параметр не превращается ни в 0, ни в NULL, выполнение падает с ошибкой.

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Товары.Ссылка,
|    Товары.Наименование
|ИЗ
|    Справочник.Номенклатура КАК Товары
|ГДЕ
|    Товары.Родитель = &Группа
|    И Товары.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар)";
Запрос.УстановитьПараметр("Группа", Группа);
Выборка = Запрос.Выполнить().Выбрать();

ВЫБРАТЬ и его ключевые слова

После ВЫБРАТЬ ключевые слова идут строго в порядке: РАЗРЕШЕННЫЕ, РАЗЛИЧНЫЕ, ПЕРВЫЕ n. РАЗРЕШЕННЫЕ молча отбрасывает записи, недоступные пользователю по ограничениям доступа, без него такой запрос падает с ошибкой прав. ПЕРВЫЕ берёт n строк, но без УПОРЯДОЧИТЬ ПО порядок строк не гарантирован, и «первая» строка окажется любой. Три цены молока и последняя из них:

Без УПОРЯДОЧИТЬ ПО Цены.Период УБЫВ запрос вернул бы одну из трёх строк, какую СУБД отдаст первой, и на тестовой базе это может случайно совпасть с ожиданием.

ВЫБРАТЬ ПЕРВЫЕ 1
    Цены.Период,
    Цены.Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры КАК Цены
ГДЕ
    Цены.Номенклатура = &Молоко
УПОРЯДОЧИТЬ ПО
    Цены.Период УБЫВ

Иерархия и табличные части

В ИЕРАРХИИ отбирает группу и всех её потомков на любой глубине. Прямых детей даёт условие Родитель = &Группа. Справочник с группой «Продукты», подгруппой «Молочное» и товарами:

Табличная часть в запросе живёт отдельной таблицей: Документ.Реализация.Товары, а строки одного документа отбирают условием ТЧ.Ссылка = &Документ.

ВЫБРАТЬ
    Товары.Наименование
ИЗ
    Справочник.Номенклатура КАК Товары
ГДЕ
    Товары.Ссылка В ИЕРАРХИИ (&Продукты)
    И НЕ Товары.ЭтоГруппа
УПОРЯДОЧИТЬ ПО
    Товары.Наименование

Строки и сравнения

Строку неограниченной длины (например, комментарий) нельзя сравнить или сгруппировать напрямую, запрос упадёт. Её приводят к фиксированной длине: ВЫРАЗИТЬ(Док.Комментарий КАК СТРОКА(200)). ПОДОБНО ищет по шаблону: % любая последовательность символов, _ ровно один символ. МЕЖДУ включает обе границы.

Как отвечать: «Почему значения передают параметрами, а не вклеивают в текст запроса?»

Строка с кавычкой или дата в чужом формате ломают текст запроса. С параметром текст один, и СУБД переиспользует план, а со вклеенными значениями каждый вызов даёт новый текст и новый план. И пользовательский ввод, вклеенный в текст, позволяет менять сам запрос, это дорога к инъекции. Перечисления и предопределённые элементы пишу через ЗНАЧЕНИЕ: это константы конфигурации, а не пользовательские данные.

В ответе есть все три причины: текст, план и безопасность, и отдельно сказано, что ЗНАЧЕНИЕ параметром не считается. Интервьюер видит, что кандидат понимает механику, а не повторяет правило.

На чём валят

  • −Ждут от ПЕРВЫЕ 1 последнюю цену без сортировки. Вернётся произвольная строка. Нужно УПОРЯДОЧИТЬ ПО с направлением.
  • −Сравнивают строку неограниченной длины напрямую. Запрос падает. Поле приводят ВЫРАЗИТЬ(… КАК СТРОКА(N)).
  • −Отбирают группу условием Родитель = &Группа и ждут вложенные подгруппы. Родитель даёт только прямых детей. Всех потомков даёт В ИЕРАРХИИ.
  • −Склеивают текст запроса со значением из поля ввода. Ломается текст и открывается инъекция. Значение передают параметром.

Проверь себя

Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.

  1. #oc_q_basics1 / 5
    Что вернёт условие Т.Ссылка В ИЕРАРХИИ (&Группа)?
    A)Только элементы без групп на всех уровнях
    B)Только прямых потомков группы, без внуков
    C)Группу и всех потомков
    D)Только саму группу
    показать ответ и разбор
    +C)Группу и всех потомков

    // разбор: В ИЕРАРХИИ проверяет, входит ли значение в иерархию указанной группы, включая саму группу и все вложенные уровни. Для прямых потомков используют условие Т.Родитель = &Группа. Работает для иерархических справочников и ПВХ.

  2. #oc_q_basics2 / 5
    Как в запросе сравнить поле с конкретным значением перечисления?
    A)Т.Статус = "Закрыт"
    B)= ЗНАЧЕНИЕ(Перечисление.Статусы.Закрыт)
    C)Т.Статус = Перечисление.Статусы.Закрыт
    D)Т.Статус = &Статусы.Закрыт
    показать ответ и разбор
    +B)`= ЗНАЧЕНИЕ(Перечисление.Статусы.Закрыт)`

    // разбор: Функция ЗНАЧЕНИЕ() в тексте запроса даёт значение перечисления, предопределённого элемента или пустой ссылки: ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка). Строка «Закрыт» — это представление, а не значение. Можно и через параметр, но ЗНАЧЕНИЕ избавляет от лишнего УстановитьПараметр.

  3. #oc_q_basics3 / 5
    Какой тип можно передать в параметр для условия Т.Ссылка В (&Список)?
    A)Только Массив
    B)Массив, список или таблица значений
    C)Только строку с перечнем значений через запятую
    D)Только СписокЗначений с пометками
    показать ответ и разбор
    +B)Массив, список или таблица значений

    // разбор: Для условия В подходит коллекция значений: Массив, СписокЗначений, ФиксированныйМассив или таблица значений с одной колонкой. Строку через запятую запрос не разберёт как список. На очень больших списках (десятки тысяч) лучше передать таблицу и соединиться с временной таблицей.

  4. #oc_q_basics4 / 5
    Что вернёт запрос?
    ВЫБРАТЬ ПЕРВЫЕ 1
      Ц.Цена
    ИЗ
      РегистрСведений.Цены КАК Ц
    ГДЕ
      Ц.Товар = &Товар
    A)Произвольную одну цену товара
    B)Последнюю по дате цену товара
    C)Первую по дате цену товара
    D)Ошибку: ПЕРВЫЕ без сортировки запрещено
    показать ответ и разбор
    +A)Произвольную одну цену товара

    // разбор: Без УПОРЯДОЧИТЬ ПО порядок строк не гарантирован, и ПЕРВЫЕ 1 возьмёт любую строку, которую первой вернёт СУБД. Сегодня это может быть самая старая цена, после перестроения индексов — другая. Последнюю цену берут срезом последних или с УПОРЯДОЧИТЬ ПО Период УБЫВ.

  5. #oc_q_basics5 / 5
    Что найдёт условие Т.Наименование ПОДОБНО "%болт%"?
    A)Наименования ровно из шести символов
    B)Только начинающиеся с «болт»
    C)Только равные «болт» без учёта регистра
    D)Содержащие «болт» где угодно
    показать ответ и разбор
    +D)Содержащие «болт» где угодно

    // разбор: В шаблоне ПОДОБНО знак % означает любую последовательность символов, _ — ровно один символ. «%болт%» — подстрока в любом месте, «болт%» — начало строки. Спецсимволы в искомом тексте экранируют через СПЕЦСИМВОЛ. Шаблон с % в начале не использует индекс по наименованию.

дальше

Теорию прочитал. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, бесплатная часть практики — одна сессия дня в сутки.