При написании запросов к информационной базе разработчики часто сталкиваются с необходимостью отфильтровать записи, в которых текстовый реквизит (например, Комментарий или Описание) заполнен. Однако при попытке стандартного сравнения вида ГДЕ Номенклатура.Комментарий <> "" платформа 1С возвращает ошибку: «Неверные параметры в операции сравнения. Нельзя сравнивать поля неограниченной длины и поля несовместимых типов».
Разберем причины возникновения этой ошибки, рассмотрим все рабочие способы проверки строки на непустоту в языке запросов 1С и проанализируем их влияние на производительность.
В реляционных СУБД (MS SQL Server, PostgreSQL, Oracle и др.) строковые поля неограниченной длины хранятся в специальных типах данных (BLOB, CLOB, nvarchar(max) или text). На уровне платформы «1С:Предприятие» для таких полей действуют строгие ограничения:
=, <>, >, <).СГРУППИРОВАТЬ ПО.УПОРЯДОЧИТЬ ПО.ПО.Для того чтобы обойти эти ограничения, необходимо использовать специальные конструкции и функции языка запросов.
Самый быстрый и лаконичный способ проверить строку неограниченной длины на непустоту — использовать оператор сопоставления с шаблоном ПОДОБНО.
Посмотрим на пример с отрицанием пустой строки:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
НЕ Номенклатура.Комментарий ПОДОБНО ""
Также можно проверить наличие как минимум одного любого символа с помощью маски _ (символ подчеркивания означает ровно один произвольный символ):
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Комментарий ПОДОБНО "%_%"
Оператор ПОДОБНО транслируется в SQL-конструкцию LIKE и корректно обрабатывает поля неограниченной длины без предварительного явного приведения типов.
Другой распространенный вариант — явное приведение строки неограниченной длины к строке фиксированной длины с помощью конструкции ВЫРАЗИТЬ. Поскольку нам важно узнать лишь факт наличия текста, достаточно выразить поле в строку минимальной длины, например, в 1 символ:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
ВЫРАЗИТЬ(Номенклатура.Комментарий КАК Строка(1)) <> ""
Конструкцию ВЫРАЗИТЬ можно использовать как в секции ГДЕ, так и в списке выборки. Важно помнить, что максимальная длина строки, которую можно задать в качестве параметра функции приведения типа, составляет 1024 символа.
Функция ПОДСТРОКА также преобразует фрагмент текста в строку ограниченной длины, что позволяет использовать стандартные операторы сравнения:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
ПОДСТРОКА(Номенклатура.Комментарий, 1, 1) <> ""
Здесь первым параметром передается поле источника, вторым — начальная позиция (1), третьим — количество выбираемых символов (1). Результат работы функции имеет ограниченную длину, поэтому сравнение <> "" выполняется без ошибок.
Если конфигурация работает на платформе версии 8.3.20 и выше, в языке запросов доступна встроенная функция ДЛИНАСТРОКИ, возвращающая количество символов в поле:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
ДЛИНАСТРОКИ(Номенклатура.Комментарий) > 0
Этот вариант делает текст запроса максимально понятным и выразительным.
При использовании условий по полям неограниченной длины важно учитывать архитектурные особенности СУБД:
ПОДОБНО, ПОДСТРОКА, ВЫРАЗИТЬ или ДЛИНАСТРОКИ) заставляет СУБД последовательно просматривать все строки таблицы. В больших базах данных это приводит к значительным задержкам.Булево (например, ЕстьКомментарий). Его значение следует заполнять автоматически в процедуре ПередЗаписью объекта:
Процедура ПередЗаписью(Отказ)
ЕстьКомментарий = НЕ ПустаяСтрока(Комментарий);
КонецПроцедуры
ГДЕ Номенклатура.ЕстьКомментарий = ИСТИНА, которое будет эффективно использовать индекс.