При написании запросов к базе данных 1С разработчики часто используют оператор проверки на соответствие шаблону ПОДОБНО. Однако при попытке найти строку, которая сама по себе содержит квадратные скобки (например, артикул, код или номер вида [000654]), процент % или знак подчеркивания _, стандартное условие начинает работать некорректно. Это происходит потому, что данные символы являются управляющими конструкциями шаблона. Разберем, как правильно экранировать служебные знаки в языке запросов платформы 1С:Предприятие.
Рассмотрим, какие именно символы зарезервированы платформой внутри строки шаблона:
% — обозначает последовательность из любого количества произвольных символов (включая нулевую длину)._ — обозначает строго один произвольный символ.[...] — обозначают любой одиночный символ из перечисленных внутри скобок (например, [0-9] или [абвг]).[^...] — обозначает любой одиночный символ, кроме тех, что перечислены внутри.Если нам необходимо найти точное вхождение одного из этих символов как обычного текста, его следует экранировать с помощью специального символа экранирования.
Проанализируем стандартный и самый надежный способ экранирования — указание директивы СПЕЦСИМВОЛ. Данная конструкция объявляется в конце выражения сравнения и задает один конкретный символ, который будет сообщать платформе: следующий за ним символ шаблона нужно воспринимать буквально.
Посмотрим на пример запроса, где в наименовании ищется подстрока [000654]:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Наименование ПОДОБНО "%\[000654\]%" СПЕЦСИМВОЛ "\"
В приведенном запросе мы назначили обратный слэш \ в качестве символа экранирования. Перед открывающей квадратной скобкой \[ и перед закрывающей \] мы указали этот спецсимвол, благодаря чему платформа воспринимает их как обычные печатные знаки текста.
Важное ограничение: литерал после ключевого слова СПЕЦСИМВОЛ обязан быть строкой длиной ровно в один символ (например, "\", "~", "#"). Передавать этот символ через параметр запроса нельзя — синтаксис языка запросов 1С требует явного указания литерала.
Рассмотрим еще одну синтаксическую особенность шаблонов. Открывающую квадратную скобку можно экранировать, поместив её внутрь самого диапазона квадратных скобок — [[]. В этом случае закрывающая скобка вне диапазона автоматически трактуется как обычный символ.
Посмотрим, как выглядит такой запрос:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Наименование КАК Наименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Наименование ПОДОБНО "%[[]000654]%"
Этот способ позволяет обойтись без конструкции СПЕЦСИМВОЛ, если требуется экранировать только квадратные скобки.
Если строка поиска вводится пользователем динамически и передается в запрос через параметр, все спецсимволы в ней необходимо предварительно экранировать во встроенном языке.
Разберем по шагам правильный алгоритм экранирования. Критически важно соблюдать очередность замен: первым делом экранируется сам назначенный символ экранирования, и только затем все остальные служебные знаки шаблона.
// Допустим, пользователь ввел строку: [000654]_тест%
СтрокаПоиска = ВходнойТекст;
// 1. В первую очередь экранируем сам escape-символ (обратный слэш)
СтрокаПоиска = СтрЗаменить(СтрокаПоиска, "\", "\\");
// 2. Экранируем процент, подчеркивание и открывающую скобку
СтрокаПоиска = СтрЗаменить(СтрокаПоиска, "%", "\%");
СтрокаПоиска = СтрЗаменить(СтрокаПоиска, "_", "\_");
СтрокаПоиска = СтрЗаменить(СтрокаПоиска, "[", "\[");
СтрокаПоиска = СтрЗаменить(СтрокаПоиска, "]", "\]");
// 3. Формируем итоговый шаблон для поиска по подстроке
ШаблонЗапроса = "%" + СтрокаПоиска + "%";
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ ""\""";
Запрос.УстановитьПараметр("Шаблон", ШаблонЗапроса);
Результат = Запрос.Выполнить();
Если нарушить последовательность и заменить слэш в последнюю очередь, все ранее расставленные знаки \ продублируются в \\, что приведет к искажению шаблона поиска.
Проанализируем влияние оператора ПОДОБНО на быстродействие базы данных:
"%[000654]%") делает невозможным использование индексов СУБД. Происходит полное сканирование таблицы (Full Scan), что на больших объемах данных приводит к длительным блокировкам и падению производительности.ПолнотекстовыйПоиск, работающий по специализированному индексу.= или поиск по префиксу ("000654%" без начального процента) позволяет СУБД эффективно использовать индекс.