При миграции серверной инфраструктуры 1С:Предприятие на новое оборудование или обновлении версии системы управления базами данных (СУБД) до Microsoft SQL Server 2022, системные администраторы и разработчики иногда сталкиваются с крайне странным поведением системы. Во всех отчетах, использующих стандартные периоды, а также в произвольных запросах, поля ПериодДень, ПериодНеделя или ПериодМесяц оказываются пустыми (значение NULL или пустая дата), хотя исходные данные в таблицах присутствуют и заполнены корректно.
Особенно загадочно выглядит ситуация, когда функция НАЧАЛОПЕРИОДА возвращает результат, если дата указана в запросе жестко (константой), но выдает пустое значение, если дата берется из физической таблицы или временной таблицы. В данной статье мы подробно разберем, почему это происходит, и как восстановить работоспособность системы.
Рассмотрим характерный пример запроса, который на старом сервере работал корректно, а на новом (с MSSQL 2022) начал возвращать пустые значения. Проблема проявляется при попытке получить начало периода от даты, которая уже находится во временной таблице или в таблице БД.
Разберем по шагам диагностический запрос, который помогает локализовать проблему:
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(ДАТАВРЕМЯ(2025, 12, 31, 23, 59, 59), ДЕНЬ) КАК ДеньПериода
ПОМЕСТИТЬ ВТ_Данные;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_Данные.ДеньПериода КАК ИсходнаяДата,
НАЧАЛОПЕРИОДА(ВТ_Данные.ДеньПериода, ДЕНЬ) КАК РезультатПусто
ИЗ
ВТ_Данные КАК ВТ_Данные;
В этой ситуации поле ИсходнаяДата будет заполнено, а РезультатПусто — нет. Это происходит потому, что платформа 1С при работе с SQL-сервером транслирует функцию НАЧАЛОПЕРИОДА в сложную математическую конструкцию на языке T-SQL, использующую функции DATEADD и DATEDIFF. Если драйвер подключения или логика оптимизатора запросов SQL-сервера дают сбой, результат вычисления даты превращается в NULL.
Выясним причину технического несоответствия. Платформа 1С:Предприятие 8.3.18.1741 и более ранние версии были выпущены задолго до выхода Microsoft SQL Server 2022. Официальная поддержка этой версии СУБД появилась только в более поздних релизах платформы, начиная с 8.3.20.2076, 8.3.21.1607 и 8.3.22.1672.
Основная проблема заключается в том, что старые версии платформы не знают об изменениях в типах данных и механизмах обработки запросов в SQL 2022. Рассмотрим подробнее, что можно сделать, если оперативное обновление платформы невозможно:
При развертывании базы на SQL Server 2022 уровень совместимости по умолчанию устанавливается в значение 160. В этом режиме SQL Server использует новые алгоритмы оптимизатора запросов, которые могут некорректно обрабатывать специфические конструкции T-SQL, генерируемые старой платформой 1С для работы с датами.
Чтобы исправить это, выполним следующие действия в SQL Server Management Studio (SSMS):
Понижение уровня совместимости заставляет СУБД использовать старую логику обработки, которая "понятна" платформе 8.3.18.
Разберем еще один критический момент. SQL Server 2022 официально больше не включает в себя и не поддерживает старый драйвер SQL Server Native Client (SNAC 11), на который жестко ориентированы старые релизы 1С. Вместо него Microsoft предлагает использовать Microsoft OLE DB Driver for SQL Server (MSOLEDBSQL).
Если на новом сервере Windows не установлен Native Client 11, сервер 1С может пытаться взаимодействовать с базой через другие механизмы, что приводит к искажению типов данных при передаче между rphost и SQL. Особенно это касается временных таблиц, где типы данных определяются динамически.
Что нужно сделать:
rphost (сервер приложений 1С).Проанализируем ситуацию со смещением дат. В 1С существует параметр "Смещение дат" (0 или 2000 лет). Если при переносе виртуалки или создании базы в консоли кластера 1С было указано смещение, отличное от того, что было на старом сервере, функции работы с периодами могут "сходить с ума", так как SQL Server хранит даты с минимальным значением 01.01.1753.
Посмотрим, как проверить этот параметр:
Если вышеперечисленные методы не помогли, нам необходимо увидеть, что именно "вылетает" из платформы в сторону SQL. Для этого воспользуемся инструментом SQL Server Profiler.
Рассмотрим, на что обратить внимание в трассировке:
DATEADD или DATEDIFF.NULL, значит проблема в том, как платформа сформировала константы для расчета начала периода. Часто это связано с неверным форматом даты или неявным приведением типов datetime к datetime2.Подводя итог, можно сказать, что проблема "пустых дат" — это классический конфликт поколений программного обеспечения. Чтобы гарантированно решить проблему, мы рекомендуем следующий порядок действий:
План действий:
EXEC sp_updatestats;
DBCC FREEPROCCACHE;
Соблюдение этих шагов позволит восстановить корректное отображение периодов в отчетах и обеспечит стабильную работу системы 1С:Предприятие на современном оборудовании.