Среди прочих инструментов, предоставляемых механизмом запросов 1С (который, как мы знаем, есть насадка-транслятор на механизмы СУБД), имеется единственный в своём роде - наложение условия шаблоном. Большинство операций реляционных СУБД работают с точными значениями или их диапазонами, и только ПОДОБНО имеет дело с маской, нечётким условием. "ПОДОБНО", он же "LIKE", есть в подавляющем большинстве современных СУБД (согласно стандарту ANSI SQL 2003), и 1С предоставляет нам возможности такого поиска единообразно, приводя средствами платформы различные тонкости СУБД к единому поведению. Возможность эта заложена в механизме запросов, отборов, отборов СКД (во всех её проявлениях), и, как показывает практика, "ПОДОБНО" действительно ведёт себя совершенно одинаково и ожидаемо и в динамических списках, и в разных запросах - везде в 1С.
Нам известны более кастомизированные механизмы - отборы и отборы СКД "Содержит"/"Не содержит". По сути они реализованы тем же образом, что и ПОДОБНО, но урезаны, и формируют строку шаблона самостоятельно (дописывают "%"). Тому есть несколько причин, от защиты ключевых мест системы от действий пользователя и разработчика, провоцирующих избыточную нагрузку, до простоты реализации в платформе.
Нам известны более гибкие механизмы - это полнотекстовый поиск. Он в СУБД реализуется отдельно от "основного движка", требует свои конструкции, индексы, и "может всё" ценой накладных расходов на разработку и поддержание. Известны также регулярные выражения и т.д.
Поиск "ПОДОБНО" опирается на штатную работу СУБД, на обращения к колонкам фактографической реляционной БД, пусть даже они строкового типа неограниченной длины. Обработка отбора "ПОДОБНО" обычно не требует специальных донастроек ни в 1С, ни в СУБД.
Как видим, возможности даже шире, чет у некоторых СУБД (хотя, например, в SQL Server такое тоже есть).
Операторы "классического" поиска:
// имеем запрос вида:
ТекстЗапроса="ВЫБРАТЬ Истина ИЗ Справочник.Сайты КАК спр ГДЕ спр.Наименование ПОДОБНО &Условие";
// и элемент справочника с наименованием "Инфостарт".
//
// в зависимости от успешности поиска Запрос.Выполнить().Пустой() будет Истина (не нашли) или Ложь (нашли)
// служебный символ "%"
Запрос.УстановитьПараметр("Условие","%фоста%"); // найдёт
Запрос.УстановитьПараметр("Условие","%фоста"); // не найдёт
Запрос.УстановитьПараметр("Условие","%фостарт"); // найдёт
Запрос.УстановитьПараметр("Условие","Инфоста%"); // найдёт
Запрос.УстановитьПараметр("Условие","Инфоста"); // не найдёт
Запрос.УстановитьПараметр("Условие","Ин%арт"); // найдёт
// служебный символ "_"
Запрос.УстановитьПараметр("Условие","_Инфостарт"); // не найдёт
Запрос.УстановитьПараметр("Условие","_нфостарт"); // найдёт
Запрос.УстановитьПараметр("Условие","Инфостар_"); // найдёт
Запрос.УстановитьПараметр("Условие","Инфоста_"); // не найдёт
Запрос.УстановитьПараметр("Условие","Ин_оста_т"); // найдёт
Операторы с квадратными скобками позволяет понять, "есть ли такая буква в этом слове". Например:
Запрос.УстановитьПараметр("Условие","Ин[клм]остарт"); // не найдёт
Запрос.УстановитьПараметр("Условие","Ин[фыва]остарт"); // найдёт
// можно чередовать и применять всё вместе:
Запрос.УстановитьПараметр("Условие","И%[фыва]_ст[^йоу]р%"); // найдёт
Также, согласно стандарту, квадратные скобки "понимают" диапазоны букв:
Запрос.УстановитьПараметр("Ин[т-х]остарт"); // определяем буквы "т, у, ф, х", найдёт
Запрос.УстановитьПараметр("Ин[б-д]остарт"); // определяем буквы "б, в, г, д", не найдёт
// можно перечислять и указывать диапазоны вперемешку:
Запрос.УстановитьПараметр("Ин[рст-ц]остарт"); // определяем буквы "р, с, т, у, ф, х, ц", найдёт
То же касается отрицаний [^..], можно задавать диапазоны символов. Напомню, порядок определяется возрастанием числовых кодов символов в таблице кодировки. При нарушенном порядке [я-а] ничего не найдётся. Сами квадратные скобки тоже можно искать: "[[]" определяет символ "[". Символы "%" и "_" в скобках означают сами себя, а не служебные wildcard.
Сложный шаблон уже даже начинает напоминать регулярное выражение. "ПОДОБНО" реализует упрощённую wildcard-семантику, где "%" заменяет классический "*", а "_" заменяет классический "?".
- Многократный повтор "%" ровно ничего не меняет, "%%%фостарт", "Ин%%%%т" и "%фостарт" равнозначны. А вот "_" требователен к знакоместам, к позициям, и следует быть внимательным к повторам, т.к. "__нфостарт" сработает, а "___нфостарт" нет.
- Все операторы не чувствительны к регистру букв, "Инф%" и "инф%" равнозначны. Интересно, что SQL по умолчанию тоже не учитывает регистр, а PostgreSQL и Оракл - учитывают.
- Все операторы корректно обрабатывают всяческие символы, т.е. коллекцию "Символы", и символ параграфа-конца страницы, и прочий мусор (есть тонкости в национальных частях кодировок, см.ниже). В том числе в конструкциях "[..] и [^..]. Такие могут фигурировать в наполнении таблицы, в условии запроса, и будут правильно найдены (ввести их в строку поиска можно программно или скопипастить откуда-нибудь). "Символ.ПС", несмотря на некоторую синтетичность CR+LF, это один символ.
- Сами себя "%" и "_" правильно находят, на общих основаниях, т.е. "Доход 20% годовых" по "%д 20% г%" будет найден.
- Не следует делать экранирование операторов, как принято в СУБД, т.е. "/%" как раз-таки не сработает. Для экранирования и для уточнения используется оператор "СПЕЦСИМВОЛ" (он же Escape):
// имеем запрос вида:
ТекстЗапроса="ВЫБРАТЬ Истина ИЗ Справочник.Сайты КАК спр ГДЕ спр.Наименование ПОДОБНО &Условие";
// надо найти именно элемент с наименованием "Инфостарт_Сайт", а не "Инфостарт Сайт"
// поиск по шаблону "Инфостарт_Сайт" выдаст оба элемента.
Поэтому следует изменить запрос:
ТекстЗапроса="ВЫБРАТЬ Истина ИЗ Справочник.Сайты КАК спр ГДЕ спр.Наименование ПОДОБНО &Условие" СПЕЦСИМВОЛ""$""";
// поиск по шаблону "Инфостарт$_Сайт" выдаст только нужное.
Поиск возможен в строковых полях таблиц (в т.ч. неограниченной длины), в переменных неограниченной длины (в т.ч. полях таблиц-параметров и временных таблиц). Но при этом поиск невозможен в полях, полученных функцией "ПредставлениеСсылки", или имеющих, явно или потенциально, значение Null. Если таковое явственно, то даже компиляция, в т.ч. открытие конструктора запроса/СКД, сообщает об ошибке "Неверные параметры", если же нет, то будет ошибка исполнения запроса.
Отбор средствами СКД для "ПОДОБНО" имеет дело с значением колонки таблицы и может использовать индексы, т.е. быть ускорен (в SQL и Oracle так и есть), и создаваемая им нагрузка наблюдаема в профайлере обычным образом. Замечено, что запрос на несколько значений одного и того же поля "спр.Путь ПОДОБНО ""%фостар%"" ИЛИ спр.Путь ПОДОБНО ""%тар_"" и т.д., оптимизируется почти всегда, поэтому опасаться критичного торможения при наложении условия, моделирующего "подобие в списке" для одного поля, не стоит. А вот условия на разные поля, конечно, дадут рост нагрузки и, возможно, мер по оптимизации запроса.
Определённую тонкость представляет кодировка. 1С использует Unicode, и вроде бы защищает нас от специфики СУБД, но, поскольку есть "Внешние источники", запросы и СКД к ним, упомяну о кодировке.
В MS SQL понимание кодировки зависит от SSMS, стыковки сервера скуля с провайдером, правильно выставленного свойства БД Collation (Cyrillic_General_CI_AS). Иногда where f1 like '%нфост%' не работает, а where f1 like N'%нфост%' работает, т.е. стоит перед литеральными юникодными строками писать "N" или делать так: "f1 LIKE Convert(VarChar,N'%нфост%')". Также советуют для юникода применять функции NCHAR(), UNICODE() и т.д, а не CHAR(), ANSI() и т.д. SQL иначе учитывает завершающие пробелы, и с кодировкой ASCII работает по своим старым стандартам, а не по ISO.
В Оракле: есть просто разные операторы:
"обычный" LIKE — применяется для запроса к строковым столбцам с традиционными кодировками;
LIKEC — применяется для столбцов с кодировкой Unicode (в терминологии Oracle — Unicode complete);
LIKE2 — для кодировки UCS2;
LIKE4 — для кодировки UCS4.
Насчёт внешних источников в методическом описании 1С сказано:
"Строковые функции и выражения запроса и СКД преобразуются в запрос к СУБД с использованием управляющих последовательностей ODBC (ODBC Escape Sequences, http://msdn.microsoft.com/en-us/library/windows/desktop/ms715364(v=vs.85).aspx", причём там речь о функции "Подстрока", а "ПОДОБНО" не упомянут вообще нет, но на практике эффект тот же. В других статьях 1С на эту тему никакие ограничения вообще не упомянуты.
И, повторюсь, благодаря 1С в "классических" случаях мы можем не заботиться о кодировке. 1С найдёт даже кракозябр в строке ему подобных.
Пожалуй, всё. Углубляться в дебри реализации "Like" средствами СУБД не будем.