Как стать автором
Обновить

1С: Предприятие, восстановление индексов СУБД

Добрый день!

Занимаюсь разработкой конфигураций на основе платформы 1С: Предприятие. При разворачивании копии базы сформированной средствами 1С: Предприятие регулярно появлялась ошибка:

В процессе обновления информационной базы произошла критическая ошибка
по причине:
Попытка вставки неуникального значения в уникальный индекс:
Microsoft SQL Server Native Client 11.0: Выполнение инструкции CREATE UNIQUE INDEX прервано, поскольку обнаружен повторяющийся ключ для объекта с именем «dbo._AccRg2024NG» и индекса с именем "_AccRg2024_ByPeriod_TRNNG". Повторяющееся значение ключа: (сен 30 4013 12:00AM, 0x0000001c, 0x83fd001b78e2ed3011e342e2cb8d7e1c, 1).
HRESULT=80040E2F, SQLSrvr: SQLSTATE=23000, state=1, Severity=10, native=1505, line=1


Так как копии разворачивались только в целях внесения изменений в конфигурацию и тестирования, этой ошибке не предавали особого значения, пока не понадобилось добавить предопределенный счет. При обновлении конфигурации происходила реструктуризация регистра бухгалтерии и вываливалась данная не приглядная ошибка. Дальнейшее обновление прекращалось. Гугление данного вопроса результатов не дало. пришлось разбираться самим.

Выяснение имени таблицы 1С связанной с объектом определяется функцией ПолучитьСтруктуруХраненияБазыДанных, там же можно поглядеть и состав индексов.

Как оказалось данные индексы в таблице SQL "_AccRg2024" отсутствовали физически. При дальнейшем анализе данных уже средствами SQL выяснилось, что не уникальными были номера записей в разрезе Периода — [_Period], регистратора — [_RecorderRRef] и номер записи [_LineNo], из за чего и не происходила реструктуризация таблицы. Кто и как умудрился удалить эти индексы история умалчивает, данный факт восстановлению не подлежит.

Вылечилась данная ситуация следующим запросом:

USE [DB]
GO

CREATE TABLE #TempRecorder (_RecorderRRef BINARY(16))
GO

INSERT INTO #TempRecorder 
	SELECT T.[_RecorderRRef]
	FROM (SELECT COUNT(*) as _count , T1.[_Period]  ,T1.[_RecorderRRef] ,T1.[_LineNo]      
			FROM [dbo].[_AccRg2024] AS T1	 
			GROUP BY T1.[_Period] ,T1.[_RecorderRRef]  ,T1.[_LineNo]
			HAVING count(*) > 1 ) AS T
	
	--WHERE T.[_RecorderRRef] = 0xBA80000C29053BCD11E2FF4303EA5AA7

	GROUP BY T.[_RecorderRRef]

DECLARE @_Count numeric(10), @_Period datetime, @_RecorderRRef binary(16), @_LineNo numeric(9,0);

DECLARE @i int;
SET @i = 0;

DECLARE _Recorder_Cursor CURSOR FOR
SELECT * FROM #TempRecorder;

OPEN _Recorder_Cursor
FETCH NEXT FROM _Recorder_Cursor INTO @_RecorderRRef;

WHILE @@FETCH_STATUS = 0
   
	BEGIN
		DECLARE _Cursor CURSOR FOR
		SELECT [_Period], [_LineNo] FROM [dbo].[_AccRg2024]
		WHERE [_RecorderRRef] = @_RecorderRRef

		OPEN _Cursor

		SET @i=0;

		FETCH NEXT FROM _Cursor INTO @_Period, @_LineNo

		WHILE @@FETCH_STATUS = 0

			BEGIN
				SET @i = @i + 1 

				UPDATE [dbo].[_AccRg2024] SET [_LineNo] = @i
				WHERE CURRENT OF _Cursor

				FETCH NEXT FROM _Cursor INTO @_Period, @_LineNo

			END;

		CLOSE _Cursor;
		DEALLOCATE _Cursor;

	FETCH NEXT FROM _Recorder_Cursor INTO @_RecorderRRef;
	
	END

CLOSE _Recorder_Cursor;
DEALLOCATE _Recorder_Cursor;

GO

DROP TABLE #TempRecorder
GO

Изначально определяются неуникальные записи, выбираются регистраторы и в цикле происходит пере нумерация строк.

После этого, уже средствами 1С, выполнилось тестирование базы с режимом «Реструктуризация таблиц информационной базы», данная процедура пересоздала индексы в таблице, и дальнейшие манипуляции, при работе с метаданными конфигурации, стали происходить без каких либо ошибок.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.