При обновлении конфигураций 1С вы можете столкнуться с неприятной ошибкой: «Таблица метаданных истории данных содержит не уникальные записи». Эта проблема блокирует процесс обновления и обычно указывает на сбой в работе платформенного механизма «История данных». Давайте разберем, почему это происходит и как безопасно исправить ситуацию.
Механизм История данных отслеживает изменения в структуре метаданных. В базе данных существует служебная таблица _DataHistoryMetadata, которая хранит версии метаданных. Каждая версия имеет номер _MetadataVersionNumber и флаг актуальности _IsActual. В норме для каждого объекта метаданных должна быть только одна запись с флагом _IsActual = 1.
Ошибка возникает, когда в силу программного сбоя платформа «забывает» снять флаг актуальности со старой версии. В результате в таблице образуется несколько «актуальных» записей для одного объекта, что делает структуру базы данных логически противоречивой.
Прежде чем выполнять любые манипуляции с таблицами базы данных через SQL, обязательно создайте полную резервную копию базы данных. Прямое вмешательство в таблицы _DataHistoryMetadata является крайней мерой. Если проблему можно решить очисткой или отключением истории данных средствами конфигуратора — попробуйте сделать это в первую очередь.
Если вы не используете платформенную историю данных или готовы рискнуть потерей истории для части объектов, можно удалить лишние записи. Мы рекомендуем удалять записи, которые не являются актуальными.
Разберем пример запроса для удаления версий, номер которых больше единицы:
DELETE FROM [dbo].[_DataHistoryMetadata]
WHERE [_MetadataVersionNumber] > 1;
Более точный подход — удаление всех записей, которые не помечены как актуальные (_IsActual = 0):
DELETE FROM [dbo].[_DataHistoryMetadata]
WHERE [_IsActual] = 0;
Это наиболее предпочтительный метод, так как он сохраняет данные истории, просто исправляя «логический беспорядок». Суть метода заключается в том, чтобы программно сбросить флаг _IsActual для всех версий, кроме той, у которой самый высокий номер версии для данного объекта.
Выполним это в два этапа (или одним запросом UPDATE с объединением):
UPDATE _DataHistoryMetadata
SET _IsActual = 0x00
FROM (
SELECT _MetadataId, MAX(_MetadataVersionNumber) AS LastVersionNumber
FROM _DataHistoryMetadata
GROUP BY _MetadataId
) AS MaxVersions
WHERE _DataHistoryMetadata._IsActual = 0x01
AND _DataHistoryMetadata._MetadataVersionNumber <> MaxVersions.LastVersionNumber
AND _DataHistoryMetadata._MetadataId = MaxVersions._MetadataId;
_MetadataId. В идеале для каждого идентификатора должна остаться только одна строка с _IsActual = 1.История данных для проблемных объектов или перехода на штатный механизм Версионирование объектов в составе БСП.Помните, что структуры таблиц в различных СУБД (MS SQL, PostgreSQL) могут отличаться префиксами полей (например, _fld). Перед выполнением запроса на рабочей базе всегда проверяйте реальные имена колонок в вашей СУБД с помощью инструментов администрирования баз данных. Для анализа реальных имен таблиц и колонок можно использовать обработку для просмотра структуры хранения базы данных.