При переходе с одной версии платформы на другую программисты часто сталкиваются с ситуацией, когда проверенные временем отчеты начинают вести себя непредсказуемо. Одной из самых коварных проблем является разное поведение Системы компоновки данных (СКД) при обработке одного и того же запроса с идентичными настройками отборов. В этой статье мы разберем, почему на платформе 8.3.10 отчет может выдавать пустой результат, а на 8.3.17 работать корректно, и как это исправить.
Рассмотрим ситуацию: у нас есть сложный запрос, использующий объединения (ОБЪЕДИНИТЬ ВСЕ) или пакеты запросов. На старых релизах платформы (например, 8.3.10) отбор, установленный пользователем в настройках, может применяться не к итоговому результату, а «проталкиваться» внутрь вложенных запросов. Если в разных частях объединения поля имеют одинаковые псевдонимы, но разный смысл или структуру, возникает конфликт имен. Платформа может ошибочно наложить отбор там, где данные не соответствуют условию, что в итоге приводит к пустой таблице.
Выясним причину такого поведения. Начиная с версий 8.3.14 и выше, компания 1С существенно оптимизировала компоновщик макета. Основные изменения коснулись механизма Filter Push-down (проталкивание фильтров). В новых версиях платформы алгоритмы анализа текста запроса стали более «интеллектуальными», позволяя более точно определять, куда именно в SQL-запросе нужно подставить условие WHERE.
Проанализируем ключевые технические факторы, влияющие на результат:
8.3.17 была проведена унификация применения отборов между «Набором данных - объединение» и «Набором данных - запрос» с внутренними объединениями. Ранее СКД могла по-разному интерпретировать поля, если они имели одинаковые синонимы в разных частях UNION.Автозаполнение = Истина) СКД сама решает, какие поля доступны для отбора. Если в запросе есть поле Статья, которое встречается в трех разных вложенных таблицах, старая платформа могла запутаться, к какой именно «Статье» относится пользовательский фильтр.Чтобы понять, что именно идет не так, нам недостаточно видеть текст запроса в схеме компоновки. Нам нужно увидеть тот запрос, который СКД отправляет в СУБД. Проанализируем ситуацию с помощью Консоли системы компоновки данных.
Выполним следующие действия:
8.3.10.8.3.17.ГДЕ (WHERE).Чаще всего мы увидим, что на старой платформе условие отбора накладывается на промежуточную временную таблицу, в которой данных, подходящих под фильтр, еще просто нет или они некорректно типизированы из-за конфликта имен.
Если мы столкнулись с тем, что отбор «шалит», наиболее эффективным способом будет ручная корректировка псевдонимов полей в финальной части запроса. Рассмотрим пример. Предположим, у нас есть запрос с объединением, где поле называется Статья.
Вместо того чтобы оставлять это имя, создадим итоговый пакет запроса, где явно переименуем результирующее поле. Посмотрим на пример изменения структуры запроса:
// Было (упрощенно):
ВЫБРАТЬ Статья, Сумма ИЗ (
ВЫБРАТЬ СтатьяЗатрат КАК Статья, Сумма ИЗ Таблица1
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ СтатьяДДС КАК Статья, Сумма ИЗ Таблица2
) КАК ВложенныйЗапрос
// Стало (решение конфликта):
ВЫБРАТЬ Статья КАК СтатьяИтог, Сумма ИЗ (
ВЫБРАТЬ СтатьяЗатрат КАК Статья, Сумма ИЗ Таблица1
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ СтатьяДДС КАК Статья, Сумма ИЗ Таблица2
) КАК ВложенныйЗапрос
После изменения текста запроса необходимо выполнить следующие действия в конструкторе СКД:
СтатьяИтог.Статья на новое — СтатьяИтог.Важный момент: Переименование поля в СтатьяИтог заставляет компоновщик макета накладывать отбор именно на результирующую выборку, так как имя поля становится уникальным и не встречается во вложенных частях запроса. Это гарантирует одинаковый результат на любой версии платформы.
Разберем еще несколько рекомендаций, которые помогут избежать подобных проблем в будущем:
ОБЪЕДИНИТЬ ВСЕ старайтесь использовать временные таблицы. Это упрощает работу оптимизатору СКД и делает процесс наложения отборов более прозрачным.Период, Счет или Организация автоматически подставляются в параметры виртуальных таблиц (например, Обороты). Если вы используете эти поля в объединениях, следите, чтобы они имели одинаковые типы и имена.Подводя итог, можно сказать, что разница в работе СКД на платформах 8.3.10 и 8.3.17 — это следствие развития продукта и улучшения алгоритмов оптимизации. Если ваш отчет перестал работать, первым делом проанализируйте итоговый макет и устраните неоднозначность имен полей. Это сделает ваш код более надежным и независимым от обновлений платформы.