2015-08-12 6 views
2

Я создал приложение, и я использовал этот фрагмент кода (который я нашел в Интернете), чтобы очистить все данные и сбросить столбцы Identity of Identity столы.Сбросить идентификатор столбца в базе данных SQL Server

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' 
GO 

EXEC sp_MSForEachTable 'DELETE FROM ?' 
GO 

EXEC sp_MSForEachTable 'DBCC CHECKIDENT(''?'', RESEED, 0)' 
GO 

EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL' 
GO 

Но у меня есть две таблицы, которые не имеют Identity столбцов, и это дает мне проблему, говоря:

Msg 7997, уровень 16, состояние 1, строка 616
'SupplierBalance' не содержат столбец идентичности.

Msg 7997, Level 16, State 1, Line 616
«CustomerBalance» не содержит идентификационный столбец.

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

спасибо.

+2

Я полагаю, что использование 'TRUNCATE' будет обновлять ваш столбец' IDENTITY', поэтому вам не нужно вызывать команду 'RESEED'. –

+0

Afaik @felix правильный. Таблица усечения не только будет обновлять ваши идентификационные коды, но и самый быстрый способ удалить содержимое всей таблицы, так как она не зарегистрирована в журнале sql. –

+0

@ ZoharPeled, вопреки распространенному мнению. 'TRUNCATE' * минимально * зарегистрирован. http://dba.stackexchange.com/questions/30325/delete-vs-truncate/30347#30347 –

ответ

3

Вместо того, чтобы использовать DELETE и выдавая команду RESEED, вы можете использовать вместо этого TRUNCATE.

EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL' 
GO 

EXEC sp_MSForEachTable 'TRUNCATE TABLE ?' 
GO 

EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL' 
GO 

Использование TRUNCATE также более эффективно, чем использование DELETE. По словам Пола Уайта в его ответе here:

Да. TRUNCATE TABLE является более эффективным по ряду причин: может потребоваться

  1. Меньшее замки. Обычно для усечения требуется только блокировка модификации схемы на уровне таблицы (и исключающие блокировки на каждой степени освобождены). При удалении могут появляться блокировки с меньшей детализацией (строка или страница), а также эксклюзивные блокировки на любых страницах, снятых с производства.

  2. Только усечение гарантирует, что все страницы будут удалены из таблицы кучи. Удаление может оставлять пустые страницы в куче, даже если указана эксклюзивная подсказка для блокировки (например, если для базы данных включен уровень изоляции строк с версией).

  3. Усечение всегда минимально регистрируется (независимо от используемой модели восстановления). В журнале транзакций записываются только операции снятия страницы.

  4. Усечение может использовать отложенную каплю, если объект имеет размер 128 экстентов или больше. Отложенное падение означает, что фактическая работа по освобождению - выполняется асинхронно по потоку фонового сервера.

Кроме того, я beleve sp_MSforEachTable недокументированные.Вы можете найти альтернативный метод here.


Поскольку некоторые из таблиц имеют FK ссылку, вы не можете использовать TRUNCATE без отбрасывания ограничений. Но все же вы можете использовать DELETE. Теперь проблема заключается в RESEED, что приводит к ошибке на таблицах без столбца IDENTITY. Чтобы решить эту проблему, вот динамический SQL, который вы можете выполнить. Это будет только RESEED, когда таблица имеет IDENTITY столбец:

DECLARE @sql NVARCHAR(MAX); 

SET @sql = N'SET NOCOUNT ON;'; 

WITH Cte(tableName, hasIdentity) AS(
    SELECT t.name, CAST(ISNULL(ic.object_id, 0) AS BIT) 
    FROM sys.tables t 
    LEFT JOIN sys.identity_columns ic 
     ON t.object_id = ic.object_id 
    WHERE t.type = 'U' 
) 
SELECT @sql = @sql + CHAR(10) + 
    N'ALTER TABLE ' + QUOTENAME(tableName) + ' NOCHECK CONSTRAINT ALL;' + CHAR(10) + 
    N'DELETE ' + QUOTENAME(tableName) + ';' + CHAR(10) + 
    CASE 
     WHEN hasIdentity = 1 THEN 
      N'DBCC CHECKIDENT(''' + QUOTENAME(tableName) + ''', RESEED, 0) WITH NO_INFOMSGS;' + CHAR(10) 
     ELSE '' 
    END + 
    N'ALTER TABLE ' + QUOTENAME(tableName) + ' WITH CHECK CHECK CONSTRAINT ALL;' 
FROM Cte 

PRINT @sql; 
EXEC sp_executesql @sql; 
+0

«TRUNCATE TABLE?» не работает в моем коде. Всякий раз, когда я его использую, он говорит, что все еще остается ограничение внешнего ключа, оставленное в таблице. – jayz

+0

Вы не можете использовать 'TRUNCATE', если есть ссылка' FK'. –

+0

Выполните удаление, а затем повторите попытку пожара - это лучшее решение, truncate не работает, даже если таблицы не имеют данных, но имеют ссылочный столбец где-то в другой таблице. –

0

1) 1-й аргумент имя таблица

2) второе ключевое слово ('Reseed') для сброса идентичности

3) третьи Далее значение Идентичность

DBCC CHECKIDENT ('ResetIDClmn', RESEED, 5) 

Пример

if OBJECT_ID('ResetIDClmn') is not null 
Begin 
Drop table ResetIDClmn 
End 
     Create table ResetIDClmn (P_Id int identity,abc varchar(10),PRIMARY KEY (P_Id)) 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 

     Select * from ResetIDClmn 

     --truncate table ResetIDClmn 

     delete ResetIDClmn where P_Id>5 

     DBCC CHECKIDENT ('ResetIDClmn', RESEED, 5) 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Insert Into ResetIDClmn (abc) values ('sdfsfd') 
     Select * from ResetIDClmn 
Смежные вопросы