Язык запросов 1С: основы и параметры
Язык запросов 1С похож на SQL, но читает объекты конфигурации, а не таблицы базы, и пишется по-русски. На собесе по основам спрашивают про параметры, порядок ключевых слов после ВЫБРАТЬ, ПЕРВЫЕ без сортировки и иерархию. Результаты запросов ниже сверены тем же запросом на PostgreSQL.
// Так спрашивают: «Зачем параметры, если можно подставить значение в текст?» «Что вернёт ПЕРВЫЕ 1 без УПОРЯДОЧИТЬ ПО?» «Как отобрать группу справочника вместе с подгруппами?» «Как сравнить строку неограниченной длины?»
Параметры
Параметр запроса обозначают &Имя и задают методом УстановитьПараметр. Значения в текст запроса не вклеивают: строка с кавычкой сломает текст, каждое новое значение даст новый текст и новый план у СУБД (система управления базами данных), а пользовательский ввод в тексте открывает дорогу инъекциям.
Перечисления и предопределённые элементы пишут прямо в тексте через ЗНАЧЕНИЕ(...): это константа конфигурации, а не пользовательские данные. Неустановленный параметр не превращается ни в 0, ни в NULL, выполнение падает с ошибкой.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Ссылка,
| Товары.Наименование
|ИЗ
| Справочник.Номенклатура КАК Товары
|ГДЕ
| Товары.Родитель = &Группа
| И Товары.ВидНоменклатуры = ЗНАЧЕНИЕ(Перечисление.ВидыНоменклатуры.Товар)";
Запрос.УстановитьПараметр("Группа", Группа);
Выборка = Запрос.Выполнить().Выбрать();ВЫБРАТЬ и его ключевые слова
После ВЫБРАТЬ ключевые слова идут строго в порядке: РАЗРЕШЕННЫЕ, РАЗЛИЧНЫЕ, ПЕРВЫЕ n. РАЗРЕШЕННЫЕ молча отбрасывает записи, недоступные пользователю по ограничениям доступа, без него такой запрос падает с ошибкой прав. ПЕРВЫЕ берёт n строк, но без УПОРЯДОЧИТЬ ПО порядок строк не гарантирован, и «первая» строка окажется любой. Три цены молока и последняя из них:
Без УПОРЯДОЧИТЬ ПО Цены.Период УБЫВ запрос вернул бы одну из трёх строк, какую СУБД отдаст первой, и на тестовой базе это может случайно совпасть с ожиданием.
ВЫБРАТЬ ПЕРВЫЕ 1
Цены.Период,
Цены.Цена
ИЗ
РегистрСведений.ЦеныНоменклатуры КАК Цены
ГДЕ
Цены.Номенклатура = &Молоко
УПОРЯДОЧИТЬ ПО
Цены.Период УБЫВИерархия и табличные части
В ИЕРАРХИИ отбирает группу и всех её потомков на любой глубине. Прямых детей даёт условие Родитель = &Группа. Справочник с группой «Продукты», подгруппой «Молочное» и товарами:
Табличная часть в запросе живёт отдельной таблицей: Документ.Реализация.Товары, а строки одного документа отбирают условием ТЧ.Ссылка = &Документ.
ВЫБРАТЬ
Товары.Наименование
ИЗ
Справочник.Номенклатура КАК Товары
ГДЕ
Товары.Ссылка В ИЕРАРХИИ (&Продукты)
И НЕ Товары.ЭтоГруппа
УПОРЯДОЧИТЬ ПО
Товары.НаименованиеСтроки и сравнения
Строку неограниченной длины (например, комментарий) нельзя сравнить или сгруппировать напрямую, запрос упадёт. Её приводят к фиксированной длине: ВЫРАЗИТЬ(Док.Комментарий КАК СТРОКА(200)). ПОДОБНО ищет по шаблону: % любая последовательность символов, _ ровно один символ. МЕЖДУ включает обе границы.
Как отвечать: «Почему значения передают параметрами, а не вклеивают в текст запроса?»
Строка с кавычкой или дата в чужом формате ломают текст запроса. С параметром текст один, и СУБД переиспользует план, а со вклеенными значениями каждый вызов даёт новый текст и новый план. И пользовательский ввод, вклеенный в текст, позволяет менять сам запрос, это дорога к инъекции. Перечисления и предопределённые элементы пишу через ЗНАЧЕНИЕ: это константы конфигурации, а не пользовательские данные.
В ответе есть все три причины: текст, план и безопасность, и отдельно сказано, что ЗНАЧЕНИЕ параметром не считается. Интервьюер видит, что кандидат понимает механику, а не повторяет правило.
На чём валят
- −Ждут от
ПЕРВЫЕ 1последнюю цену без сортировки. Вернётся произвольная строка. Нужно УПОРЯДОЧИТЬ ПО с направлением. - −Сравнивают строку неограниченной длины напрямую. Запрос падает. Поле приводят ВЫРАЗИТЬ(… КАК СТРОКА(N)).
- −Отбирают группу условием
Родитель = &Группаи ждут вложенные подгруппы. Родитель даёт только прямых детей. Всех потомков даёт В ИЕРАРХИИ. - −Склеивают текст запроса со значением из поля ввода. Ломается текст и открывается инъекция. Значение передают параметром.
Проверь себя
Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.
- Что вернёт условие
Т.Ссылка В ИЕРАРХИИ (&Группа)?A)Только элементы без групп на всех уровняхB)Только прямых потомков группы, без внуковC)Группу и всех потомковD)Только саму группупоказать ответ и разбор
+C)Группу и всех потомков// разбор: В ИЕРАРХИИ проверяет, входит ли значение в иерархию указанной группы, включая саму группу и все вложенные уровни. Для прямых потомков используют условие Т.Родитель = &Группа. Работает для иерархических справочников и ПВХ.
- Как в запросе сравнить поле с конкретным значением перечисления?A)
Т.Статус = "Закрыт"B)= ЗНАЧЕНИЕ(Перечисление.Статусы.Закрыт)C)Т.Статус = Перечисление.Статусы.ЗакрытD)Т.Статус = &Статусы.Закрытпоказать ответ и разбор
+B)`= ЗНАЧЕНИЕ(Перечисление.Статусы.Закрыт)`// разбор: Функция ЗНАЧЕНИЕ() в тексте запроса даёт значение перечисления, предопределённого элемента или пустой ссылки: ЗНАЧЕНИЕ(Справочник.Валюты.ПустаяСсылка). Строка «Закрыт» — это представление, а не значение. Можно и через параметр, но ЗНАЧЕНИЕ избавляет от лишнего УстановитьПараметр.
- Какой тип можно передать в параметр для условия
Т.Ссылка В (&Список)?A)Только МассивB)Массив, список или таблица значенийC)Только строку с перечнем значений через запятуюD)Только СписокЗначений с пометкамипоказать ответ и разбор
+B)Массив, список или таблица значений// разбор: Для условия В подходит коллекция значений: Массив, СписокЗначений, ФиксированныйМассив или таблица значений с одной колонкой. Строку через запятую запрос не разберёт как список. На очень больших списках (десятки тысяч) лучше передать таблицу и соединиться с временной таблицей.
- Что вернёт запрос?
ВЫБРАТЬ ПЕРВЫЕ 1 Ц.Цена ИЗ РегистрСведений.Цены КАК Ц ГДЕ Ц.Товар = &ТоварA)Произвольную одну цену товараB)Последнюю по дате цену товараC)Первую по дате цену товараD)Ошибку: ПЕРВЫЕ без сортировки запрещенопоказать ответ и разбор
+A)Произвольную одну цену товара// разбор: Без УПОРЯДОЧИТЬ ПО порядок строк не гарантирован, и ПЕРВЫЕ 1 возьмёт любую строку, которую первой вернёт СУБД. Сегодня это может быть самая старая цена, после перестроения индексов — другая. Последнюю цену берут срезом последних или с УПОРЯДОЧИТЬ ПО Период УБЫВ.
- Что найдёт условие
Т.Наименование ПОДОБНО "%болт%"?A)Наименования ровно из шести символовB)Только начинающиеся с «болт»C)Только равные «болт» без учёта регистраD)Содержащие «болт» где угоднопоказать ответ и разбор
+D)Содержащие «болт» где угодно// разбор: В шаблоне ПОДОБНО знак % означает любую последовательность символов, _ — ровно один символ. «%болт%» — подстрока в любом месте, «болт%» — начало строки. Спецсимволы в искомом тексте экранируют через СПЕЦСИМВОЛ. Шаблон с % в начале не использует индекс по наименованию.
дальше
Теорию прочитал. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, бесплатная часть практики — одна сессия дня в сутки.