我创建了一个应用程序,并且我使用了这段代码(我在Internet上找到)来清除所有数据并重置表格标识列的标识。
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,Level 16,State 1,Line 616
' SupplierBalance'不包含标识列。Msg 7997,Level 16,State 1,Line 616
' CustomerBalance'不包含标识列。
我想知道是否有办法重置表的列的标识,这些列只有标识列而不会出错。
谢谢。
答案 0 :(得分: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
效率更高:
可能需要更少的锁。截断通常只需要在表级别进行单个模式修改锁定(并且是独占的) 锁定每个范围解除分配)。删除可能会获取锁定 较低(行或页面)粒度以及任何的独占锁定 页面已取消分配。
只有截断才能保证从堆表中释放所有页面。删除可能会在堆中留下空页,即使是 指定了独占表锁提示(例如,如果是 为数据库启用了行版本隔离级别。
截断始终记录最少(无论使用何种恢复模式)。只有页面释放操作记录在 交易日志。
- 醇>
如果对象的大小为128个或更大,截断可以使用延迟删除。延迟下降意味着实际的重新分配工作 由后台服务器线程异步执行。
此外,我认为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;
答案 1 :(得分:0)
1)第一个参数表名称
2)重置标识的第二个关键字(' RESEED')
3)3rd Next Identity value
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