При работе с контактной информацией в системе 1С:Предприятие (например, в регистре сведений РегистрСведений.КонтактнаяИнформация) разработчики часто сталкиваются с необходимостью отфильтровать записи и получить только те, у которых заполнено поле Представление. Однако это поле имеет тип Строка (неограниченной длины).
Попытка написать простое и интуитивно понятное условие напрямую в запросе:
ГДЕ КонтактнаяИнформация.Представление <> ""
приведет к ошибке СУБД: «Нельзя сравнивать поля неограниченной длины и поля несовместимых типов». Большинство современных систем управления базами данных накладывают жесткие ограничения на прямые операции сравнения с текстовыми блоками неограниченной длины (LOB/CLOB).
В этой статье мы подробно разберем по шагам три основных способа решения этой задачи, проанализируем их плюсы и минусы с точки зрения производительности СУБД, а также выясним причину частой ошибки компиляции запроса во встроенном языке 1С.
Рассмотрим классический и официально рекомендуемый фирмой «1С» способ работы со строками неограниченной длины в условиях запроса. Он заключается в принудительном ограничении длины строки с помощью конструкции ВЫРАЗИТЬ.
Посмотрим на пример запроса, использующего этот метод:
ВЫБРАТЬ
КонтактнаяИнформация.Объект КАК Объект,
КонтактнаяИнформация.Тип КАК Тип,
КонтактнаяИнформация.Вид КАК Вид,
ВЫРАЗИТЬ(КонтактнаяИнформация.Представление КАК Строка(200)) КАК Представление
ИЗ
РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
ГДЕ
КонтактнаяИнформация.Объект = &Объект
И КонтактнаяИнформация.Тип = &Тип
И ВЫРАЗИТЬ(КонтактнаяИнформация.Представление КАК Строка(200)) <> ""
Особенности и ограничения этого метода:
ВЫРАЗИТЬ для строковых типов в запросе 1С, составляет 1024. Если вы попытаетесь написать ВЫРАЗИТЬ(... КАК Строка(1025)), платформа выдаст синтаксическую ошибку еще на этапе сохранения запроса.Еще один распространенный способ обойти ограничение СУБД — использование функции ПОДСТРОКА, которая преобразует часть неограниченной строки в строку фиксированной длины.
Проанализируем пример применения функции в условии запроса:
ГДЕ
ПОДСТРОКА(КонтактнаяИнформация.Представление, 1, 200) <> ""
Важное замечание по синтаксису: Обратите внимание, что первым символом для выделения подстроки является единица (1). Ошибочное использование нуля в качестве первого параметра (ПОДСТРОКА(..., 0, 200)) может привести к непредсказуемому поведению запроса или ошибкам СУБД.
Преимущества и недостатки функции ПОДСТРОКА:
ВЫРАЗИТЬ, функция ПОДСТРОКА позволяет извлекать фрагменты строк длиной более 1024 символов без ошибок компиляции запроса в конфигураторе.ПОДСТРОКА в секции ГДЕ крайне не рекомендуется при работе с СУБД PostgreSQL. Это может приводить к полному сканированию таблицы (Table Scan) вместо использования индексов и критическому падению скорости выполнения операции на больших объемах данных.Выясним, как проверить заполненность поля максимально быстро и без лишней нагрузки на базу данных. Наиболее производительным решением для проверки строки неограниченной длины на пустоту является использование оператора ПОДОБНО со специальным шаблоном.
Рассмотрим пример правильного условия:
ГДЕ
КонтактнаяИнформация.Представление ПОДОБНО "_%"
Разберем по шагам, как работает этот шаблон:
_ в языке запросов 1С означает ровно один любой символ.% означает последовательность символов произвольной длины (включая пустую последовательность)."_%" буквально означает: «строка, которая содержит как минимум один любой символ».Под это условие гарантированно подходят любые заполненные строки, в то время как пустые строки (длиной 0 символов) полностью отсекаются.
Почему это самый эффективный метод?
СУБД умеют напрямую применять оператор LIKE (в который транслируется ПОДОБНО) к текстовым блокам неограниченной длины. Базе данных не нужно выделять память под преобразование типов, обрезать строку или формировать подстроку. Поиск происходит на уровне СУБД максимально быстро.
Нюанс с пробелами: Строка, состоящая только из пробелов (например, " "), успешно пройдет проверку шаблоном "_%". Чтобы избежать ложных срабатываний, рекомендуется перед записью данных в базу всегда очищать строки от концевых пробелов с помощью функции встроенного языка СокрЛП().
Часто разработчики сталкиваются с тем, что условие с ПОДОБНО "_%" прекрасно отрабатывает в консоли запросов, но при переносе кода в текстовый редактор модуля 1С (например, в форму внешней обработки) система выдает ошибки компиляции:
{Форма.Форма(57,38)}: Ожидается символ ';' | И Представление ПОДОБНО ...
Проанализируем причину этой ошибки. В Консоли запросов мы пишем чистый текст запроса. Но в модуле 1С текст запроса передается в виде строкового литерала, который сам по себе заключается в двойные кавычки.
Посмотрим на ошибочный вариант кода:
// ОШИБКА: Компилятор считает, что строка запроса закрылась перед символом подчеркивания!
Запрос.Текст = " ... И КонтактнаяИнформация.Представление ПОДОБНО "_%" ";
Чтобы платформа 1С корректно восприняла кавычки, находящиеся внутри текста запроса, их необходимо **экранировать (удваивать)**.
Рассмотрим правильный вариант написания кода в модуле:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КонтактнаяИнформация.Объект КАК Объект,
| КонтактнаяИнформация.Тип КАК Тип,
| КонтактнаяИнформация.Вид КАК Вид,
| КонтактнаяИнформация.Представление КАК Представление
|ИЗ
| РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
|ГДЕ
| КонтактнаяИнформация.Объект = &Объект
| И КонтактнаяИнформация.Тип = &Тип
| И КонтактнаяИнформация.Представление ПОДОБНО ""_%""";
При таком написании компилятор встроенного языка правильно обработает двойные кавычки ""_%"", и запрос выполнится на сервере без каких-либо ошибок.