Как найти запись в SQL-базе, которая вызывает ошибку при создании начального образа РИБ?

Программист 1С v8.3 (Управляемые формы) 1С:Розница Торговля и дистрибуция
← На главную

При работе с распределенными информационными базами (РИБ) часто возникают ситуации, когда процесс создания начального образа прерывается ошибкой. Одной из самых частых причин является нарушение ограничений типа datetime в MS SQL Server. В 1С значения дат могут выходить за пределы допустимого для SQL диапазона (1753–9999 годы), что приводит к сбою. Давайте разберем, как найти такие «проблемные» записи с помощью SQL-запросов.

Понимание природы ошибки

MS SQL Server имеет жесткий диапазон для типа datetime. Если при обмене данными между базами с разным «смещением дат» (Date Offset) или из-за ошибок ввода в базу попадает запись с некорректной датой (например, 23.09.1190 или 5999 год), выполнение SQL-команд по созданию образа будет завершаться с ошибкой. Наша задача — выявить таблицы и конкретные поля, содержащие такие значения.

Шаг 1: Сканирование таблиц на наличие некорректных дат

Поскольку таблиц в структуре базы 1С очень много, мы воспользуемся динамическим SQL-запросом. Он просканирует все колонки с типами datetime и datetime2 во всех таблицах, чтобы найти записи, выходящие за рамки установленного фильтра.

Для поиска записей, создающих конфликт, мы будем использовать следующий скрипт:


DECLARE @colname NVARCHAR(150);
DECLARE @tabname NVARCHAR(150);
DECLARE @query NVARCHAR(MAX);

DECLARE @t TABLE (tabname NVARCHAR(150), colname NVARCHAR(150));
DECLARE @res TABLE (tabname NVARCHAR(150), colname NVARCHAR(150), value DATETIME2);

INSERT INTO @t (tabname, colname)
SELECT DISTINCT c.TABLE_NAME, c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.DATA_TYPE IN ('datetime', 'datetime2');

DECLARE cur CURSOR FOR SELECT tabname, colname FROM @t;
OPEN cur;
FETCH NEXT FROM cur INTO @tabname, @colname;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @query = 'INSERT INTO @res SELECT TOP 1 ''' + @tabname + ''', ''' + @colname + ''', ' + @colname + 
                 ' FROM ' + @tabname + ' WHERE ' + @colname + ' > ''3753-01-01'' OR ' + @colname + ' < ''1753-01-01''';
    
    -- Выполняем поиск для каждой таблицы
    EXEC sp_executesql @query;
    
    FETCH NEXT FROM cur INTO @tabname, @colname;
END
CLOSE cur;
DEALLOCATE cur;

SELECT * FROM @res;

Шаг 2: Анализ результатов

После выполнения запроса вы получите список, состоящий из имени таблицы (например, _AccumRg6494) и имени колонки (например, _Period). Важно понимать, что имена таблиц в SQL не совпадают с именами объектов в конфигураторе 1С.

  1. Используйте штатную обработку 1С Структура хранения информационной базы.
  2. Сопоставьте полученное в SQL имя таблицы с метаданными 1С.
  3. Найдите объект, в котором содержится некорректная дата.

Шаг 3: Исправление данных

Важное предупреждение: никогда не исправляйте данные напрямую в таблицах SQL-сервера, если вы не уверены на 100% в логической связи записей. Прямая правка через UPDATE может привести к нарушению целостности регистров и документов.

Лучшая тактика — использовать полученную информацию для поиска в 1С:

Рекомендации по настройке

Если ошибка возникает при создании РИБ, проверьте параметры смещения дат в настройках обмена. Если в главной базе и периферийной базе настройки смещения различаются, система может интерпретировать корректные даты как ошибочные. Рекомендуем также проверять регистры накопления и сведений, так как именно в них чаще всего скапливаются «битые» периоды из-за некорректных движений документов.

Данный подход позволяет локализовать проблему даже в базе объемом 96 ГБ за разумное время, минимизируя простои системы.

← На главную