При тестировании операций на файловой копии базы, выгруженной через стандартный файл выгрузки (.dt), нередко возникает ситуация, когда одна и та же последовательность документов (например, цепочка оплат, корректировок долга и регламентных документов учета НДС) дает совершенно разные результаты в файловой копии и рабочей базе на MS SQL Server. Разберем подробно, почему это происходит и как устранить расхождения.
Выгрузка информационной базы в файл .dt и последующая ее загрузка в файловый вариант — это не побайтовая копия базы данных. При выгрузке в .dt сохраняются только табличные данные и метаданные, но не переносятся таблицы предварительно рассчитанных итогов и индексы.
В момент загрузки файла .dt платформа 1С автоматически заново выполняет полный пересчет итогов по всем регистрам накопления и бухгалтерии. Если в рабочей клиент-серверной базе итоги по какой-либо причине стали неактуальными, были повреждены или граница итогов отстает от текущей даты, запросы к виртуальным таблицам остатков (например, РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки или НДСВходящий.Остатки) в рабочей и файловой базе вернут разные срезы данных.
Для устранения этой проблемы выполним следующие действия в рабочей базе:
В алгоритмах автоматического распределения сумм (зачет авансов по методу ФИФО, распределение НДС, списание партий) результат зависит от порядка строк, возвращаемых СУБД. Если в тексте запроса разработчиком не было задано строгое упорядочивание (конструкция УПОРЯДОЧИТЬ ПО), файловая СУБД 1С и MS SQL Server возвращают записи в различном физическом порядке.
Проанализируем пример кода с неоднозначной сортировкой:
// Небезопасный запрос: порядок строк на файловой СУБД и SQL может отличаться
ВЫБРАТЬ
Взаиморасчеты.Документ,
Взаиморасчеты.СуммаОстаток
ИЗ
РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&Период, Контрагент = &Контрагент) КАК Взаиморасчеты
Чтобы гарантировать одинаковый результат закрытия взаиморасчетов во всех типах СУБД, упорядочивание должно быть детерминированным:
// Корректный запрос со строгой сортировкой
ВЫБРАТЬ
Взаиморасчеты.Документ КАК Документ,
Взаиморасчеты.Документ.МоментВремени КАК МоментВремени,
Взаиморасчеты.СуммаОстаток КАК СуммаОстаток
ИЗ
РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&Период, Контрагент = &Контрагент) КАК Взаиморасчеты
УПОРЯДОЧИТЬ ПО
МоментВремени,
Документ
Если несколько документов (например, ПлатежноеПоручениеВходящее и КорректировкаДолга) введены в систему с абсолютно одинаковым временем вплоть до секунды, их взаимное положение на временной оси становится неопределенным. В файловой базе и на сервере СУБД при выборке по моменту времени они могут вставать в разную последовательность.
Разберем, как исправить хронологию:
В серверном режиме для регистров накопления активно свойство РазделениеИтогов = Истина. При высокой нагрузке остатки могут временно фиксироваться во вспомогательных таблицах сплит-итогов. Кроме того, в рабочей базе на расчет могут влиять параллельные сеансы пользователей и фоновые регламентные задания.
Для чистоты эксперимента и точного воспроизведения ошибок создадим тестовую копию средствами самого SQL Server (создание .bak-файла с последующим восстановлением в тестовую базу на сервере), а не через выгрузку в .dt. Это позволит гарантировать 100% идентичность данных, планов выполнения запросов и структуры рассчитанных итогов.