Почему оператор ПОДОБНО в запросе 1С не работает на PostgreSQL и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе с MS SQL Server на PostgreSQL разработчики часто сталкиваются с ситуацией, когда привычные и годами работающие запросы внезапно перестают возвращать данные. Одной из самых коварных проблем является использование оператора ПОДОБНО (LIKE) в сочетании с конкатенацией строк (сложением через "+") непосредственно в тексте запроса. В этой статье мы подробно разберем, почему возникает эта ошибка, как она связана с архитектурой СУБД и как правильно писать кроссплатформенные запросы, соответствующие стандартам 1С.

Суть проблемы: почему на MS SQL работает, а на PostgreSQL — нет?

Рассмотрим классическую ситуацию. Разработчик хочет найти номенклатуру, в названии которой встречается определенный шаблон, обрамленный фиксированным текстом. В коде это часто выглядит так:


Запрос.Текст = "ВЫБРАТЬ
               |    Номенклатура.Наименование КАК Наименование
               |ИЗ
               |    Справочник.Номенклатура КАК Номенклатура
               |ГДЕ
               |    Номенклатура.Наименование ПОДОБНО ""%Группа "" + &Шаблон + ""%""";

На MS SQL Server этот запрос отработает без проблем. Однако при выполнении того же кода в базе на PostgreSQL результат окажется пустым, даже если в базе точно есть подходящие записи. Разберем по шагам причины такого поведения:

  1. Особенности типизации строк: PostgreSQL очень строго относится к типам данных CHAR и VARCHAR. При сложении строк разной длины или параметров внутри запроса транслятор 1С может преобразовывать их таким образом, что в итоговый шаблон поиска добавляются невидимые завершающие пробелы. В результате вместо поиска по строке %Группа А% СУБД ищет %Группа А %, что не соответствует реальным данным.
  2. Различия в операторах конкатенации: MS SQL использует символ + для сложения строк, в то время как PostgreSQL использует стандартный SQL-оператор ||. Платформа 1С берет на себя трансляцию этих знаков, но при сложных вложенных конструкциях внутри ПОДОБНО логика формирования итогового SQL-выражения может приводить к некорректной интерпретации спецсимволов.
  3. Обработка NULL: В PostgreSQL любая конкатенация строки со значением NULL всегда дает NULL. Если параметр &Шаблон по какой-то причине окажется не определен, все условие ГДЕ превратится в ПОДОБНО NULL, и результат будет пустым.

Правильное решение: подготовка параметра на стороне встроенного языка

Согласно стандартам разработки 1С, параметры запроса должны передаваться в максимально "готовом" виде. Это гарантирует предсказуемое поведение на любой СУБД и оптимальную производительность. Выясним, как переписать наш запрос правильно.

Вместо того чтобы заставлять СУБД складывать строки во время выполнения поиска, мы должны подготовить итоговую строку поиска заранее в коде 1С и передать её как один параметр.

Рассмотрим правильный пример реализации:


// Подготавливаем шаблон поиска заранее
ПолныйШаблон = "%Группа " + СтрокаШаблона + "%";

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
               |    Номенклатура.Наименование КАК Наименование
               |ИЗ
               |    Справочник.Номенклатура КАК Номенклатура
               |ГДЕ
               |    Номенклатура.Наименование ПОДОБНО &ПолныйШаблон";

Запрос.УстановитьПараметр("ПолныйШаблон", ПолныйШаблон);
Результат = Запрос.Выполнить();

Такой подход полностью решает проблему совместимости с PostgreSQL по следующим причинам:

Анализируем влияние на производительность

Важно понимать, что использование вычислений (таких как ВЫРАЗИТЬ, ПОДСТРОКА или конкатенация строк +) в секции ГДЕ или ПОДОБНО крайне негативно сказывается на скорости работы. Проанализируем ситуацию: когда СУБД видит конструкцию ПОДОБНО "%строка" + &Параметр, она вынуждена вычислять значение выражения для каждой строки таблицы перед сравнением.

Это приводит к полному сканированию таблицы (Full Table Scan), даже если у вас созданы идеальные индексы. Передача готового параметра позволяет серверу базы данных заранее построить план выполнения и минимизировать нагрузку на дисковую подсистему.

Особенности использования спецсимволов в PostgreSQL

При работе с PostgreSQL стоит помнить об управляющих символах. Если ваш &Шаблон сам может содержать символы %, _ или обратный слэш \, их необходимо экранировать. В 1С для этого предусмотрено ключевое слово СПЕЦСИМВОЛ (ESCAPE).

Пример использования с экранированием:


// Допустим, мы ищем строку, содержащую реальный процент "%"
// Нам нужно заменить "%" на "/%" в параметре и указать "/" как спецсимвол
ПоискСПроцентом = "%" + СтрЗаменить(ТекстПоиска, "%", "/%") + "%";

Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Товары 
               |ГДЕ Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ ""/""";
Запрос.УстановитьПараметр("Шаблон", ПоискСПроцентом);

Подведем итоги

Проблема с ПОДОБНО на PostgreSQL — это не баг платформы, а следствие различий в реализации стандартов SQL разными производителями СУБД. Для того чтобы ваш код работал стабильно и быстро в любой среде, следуйте простым правилам:

  1. Никогда не используйте оператор "+" внутри условий запроса, если этого можно избежать.
  2. Формируйте строку поиска целиком во встроенном языке 1С перед вызовом Запрос.Выполнить().
  3. Соблюдайте стандарты разработки 1С, которые прямо запрещают сложные выражения в правой части оператора ПОДОБНО для обеспечения кроссплатформенности.
  4. Учитывайте поведение NULL и всегда проверяйте входные параметры перед их подстановкой в шаблон поиска.

Соблюдение этих рекомендаций позволит вам избежать "поломок" при миграции баз данных и обеспечит высокую скорость работы ваших информационных систем на базе PostgreSQL.

← На главную