При миграции информационной базы 1С:Предприятия 7.7 с формата файлов DBF на MS SQL Server стандартными средствами («Выгрузить данные» — «Загрузить данные») нередко возникает критическая ситуация: документы и справочники переносятся полностью, но на начало рабочего периода напрочь исчезают входящие остатки по регистрам накопления. Если посмотреть таблицы напрямую, выясняется, что в исходной DBF-базе остатки за прошлые годы есть, а в новой SQL-базе таблицы регистров содержат данные лишь с недавнего времени либо вовсе пусты. Разберем механику этой проблемы и рассмотрим рабочие способы её решения.
Чтобы понять причину сбоя, проанализируем, как платформа 1С 7.7 хранит и выгружает данные регистров накопления. Для каждого регистра в структуре базы создаются две связанные таблицы:
Штатный механизм выгрузки данных платформы (архив 1Cv7.DAT) устроен так, что таблицы RG* в архив не включаются вообще. С точки зрения разработчиков платформы, итоги являются производными данными. При загрузке архива в новую базу (хоть в SQL, хоть в чистую DBF) платформа автоматически пересчитывает таблицу RG* с нуля на основании строк из таблицы движений RA*.
Проблема возникает тогда, когда над базой ранее проводилась некорректная «ручная» срезка: предыдущие специалисты физически очистили старые записи движений в RA* для уменьшения размера файлов, а рассчитанные остатки просто оставили прямой записью в файле RG* без создания официального документа-регистратора. В исходной базе DBF такие «оторванные» остатки продолжают читаться до первого полного пересчета итогов, но при стандартной выгрузке/загрузке они безвозвратно теряются, так как в RA* записей нет и восстановить остатки платформе неоткуда.
Самый надежный способ, гарантирующий, что база в SQL будет жить долго, а будущие регламентные операции и тестирование с исправлением не разрушат итоги, — вернуть остаткам легитимный документ-регистратор. Разберем этот процесс по шагам.
31.12.2015 23:59:59). Для каждого регистра выгрузим остатки по всем разрезам измерений и ресурсов.RA* появятся реальные строки движений, привязанные к документу.1Cv7.DAT и загрузим её в MS SQL Server. Платформа штатно рассчитает итоги, и входящие остатки будут полностью восстановлены.Если сроки поджимают или структуру конфигурации категорически запрещено менять, можно перенести сформированные таблицы итогов RG* напрямую из файлов DBF в базу MS SQL Server. Однако важно помнить: любой последующий запуск тестирования и исправления с пересчетом итогов или сдвиг точки актуальности назад в такой базе сотрет эти данные.
Рассмотрим, как выглядит попытка загрузки через COM-соединение ADODB по одной строке, и почему она вызывает катастрофическое падение скорости:
ADOSoedinenie = New COMОбъект("ADODB.Connection");
Command = New COMObject("ADODB.Command");
// Выполнение одиночных вставок в цикле
Command.CommandText = "INSERT INTO [v77].[dbo].[RG1207] (PERIOD, SP1208, SP1209, SP1210) VALUES (Convert(datetime,'01/08/2016',103), ' LTK1 ', ' 2N OGM51 ', 0)";
Command.Execute();
При таком подходе таблица из 6–7 миллионов записей вставляется сутками. Причина проста: на каждую команду INSERT СУБД открывает неявную транзакцию, делает запись в журнал транзакций (LDF) и заново перестраивает дерево индексов таблицы.
Если мы выбираем путь прямой загрузки, оптимизируем работу с СУБД, применив следующие технические приемы:
ALTER INDEX [ИмяИндекса] ON [Таблица] DISABLE;. После завершения всей вставки перестраиваем их заново вызовом REBUILD.Simple (Простая), чтобы исключить лавинообразный рост лога транзакций.INSERT используем утилиту bcp, T-SQL команду BULK INSERT, связные серверы (Linked Server через OLE DB к каталогу DBF) либо компонент SqlBulkCopy.Также учитываем специфику типов данных: поле PERIOD в таблицах RG* на стороне SQL Server имеет тип DATETIME (всегда первое число месяца со временем 00:00:00.000), строковые идентификаторы (Base36) имеют фиксированную длину CHAR с выравниванием пробелами, а числовые поля строго соответствуют формату NUMERIC.