В процессе эксплуатации конфигурации «Зарплата и управление персоналом» (ЗУП) редакции 3.1 (особенно часто в релизе 3.1.13.75) системные администраторы и программисты могут столкнуться с критической ошибкой при попытке открыть документы «Больничный лист», «Кадровый перевод» или при формировании отчетов, таких как личная карточка Т-2. Сообщение об ошибке выглядит следующим образом: «Внутренняя ошибка: был достигнут предел служб выражений. Проверьте потенциально сложные выражения в запросе и постарайтесь их упростить». Эта проблема напрямую связана с тем, как СУБД Microsoft SQL Server обрабатывает запросы, генерируемые платформой 1С.
Рассмотрим природу этой ошибки. Проблема кроется в механизме трансляции запросов 1С в язык T-SQL. В определенных релизах логика расчета стажа была изменена таким образом, что результирующий SQL-запрос содержал избыточное количество вложенных условий CASE или операторов OR. У Microsoft SQL Server (особенно версий 2008 и 2008 R2) существуют жесткие внутренние лимиты на глубину дерева выражений. Когда количество вложенных элементов превышает определенный порог (обычно около 1000 уровней), парсер SQL-сервера прекращает работу и выдает ошибку.
Ниже мы разберем по шагам, как диагностировать и устранить данную неисправность, используя различные подходы: от оперативного исправления данных до обновления конфигурации.
Первым делом проанализируем текущую версию вашей базы данных. Ошибка была официально признана разработчиками 1С и зарегистрирована под номером 10221373. Проблема была вызвана тем, что в модуле КадровыйУчетРасширенный формировался гигантский запрос к базе данных при расчете стажа сотрудника.
Разберем алгоритм действий:
Иногда причиной «раздувания» запроса становятся некорректные данные в информационной базе. SQL-сервер пытается обработать аномальные значения дат, что приводит к усложнению логики выполнения. Проанализируем ситуацию с данными о стаже.
Выясним причину в данных:
Если у сотрудника введены данные стажа с очень ранней датой (например, 208 год или 01.01.1899), 1С генерирует дополнительные условия для корректного преобразования типов дат в SQL. Чтобы исправить это, выполним следующие действия:
e1cib/list/РегистрСведений.СтажиФизическихЛиц.Если по каким-то причинам оперативное обновление конфигурации невозможно (например, база сильно доработана), мы можем применить временную «заплатку» в виде расширения. Проанализируем программный код модуля.
Проблема локализована в общем модуле КадровыйУчетРасширенный, а именно в функции ЗапросВТРасчетСтажа. Мы можем заменить текущую реализацию функции на код из предыдущего стабильного релиза (например, 3.1.12), где расчет стажа выполнялся по другой схеме.
Пример структуры расширения для исправления:
&Вместо("ЗапросВТРасчетСтажа")
Экспорт
Функция Испр_ЗапросВТРасчетСтажа(ОписательВТ, ИмяВТРасчетСтажа = "ВТРасчетСтажа")
// Здесь размещается программный код из стабильного релиза,
// который формирует более простой SQL-запрос без чрезмерной вложенности CASE.
// ...
КонецФункции
Важно помнить, что использование расширений — это временная мера. После того как появится возможность обновить основную конфигурацию, расширение следует отключить и проверить работоспособность типового механизма.
Выясним, почему ошибка проявляется не у всех. Как показывает практика, ошибка чаще всего возникает на MS SQL Server 2008. На более современных версиях (2014, 2016, 2019) лимиты служб выражений значительно расширены, и тот же самый запрос от 1С может успешно выполняться.
Рассмотрим административные варианты решения:
DBCC FREEPROCCACHE. Внимание! Это может временно снизить производительность всей системы, так как планы запросов будут строиться заново..dt и развернуть ее в файловом варианте. Файловая версия 1С не имеет ограничений, присущих парсеру MS SQL, и позволит сформировать нужные документы.Резюмируем: Основной причиной ошибки является неудачная оптимизация запроса в релизе 3.1.13.75, которая входит в конфликт с ограничениями старых версий MS SQL Server. Самым надежным и правильным способом решения является обновление до релиза 3.1.13.76, где данная ошибка была исправлена на уровне программного кода конфигурации.