我有一个数据库的测试环境,我想在测试周期开始时用新数据重新加载该数据库。我对重建整个数据库不感兴趣——只是简单地“重新设置”数据。
使用TSQL从所有表中删除所有数据的最佳方法是什么?是否有可以使用的系统存储过程、视图等?我不想为每个表手动创建和维护截断表语句-我更希望它是动态的。
我有一个数据库的测试环境,我想在测试周期开始时用新数据重新加载该数据库。我对重建整个数据库不感兴趣——只是简单地“重新设置”数据。
使用TSQL从所有表中删除所有数据的最佳方法是什么?是否有可以使用的系统存储过程、视图等?我不想为每个表手动创建和维护截断表语句-我更希望它是动态的。
当前回答
如果你想在一个特定的表(即静态查找表)中保留数据,同时删除/截断同一数据库中其他表中的数据,那么你需要一个循环,其中包含异常。这就是我在无意中发现这个问题时所寻找的。
sp_MSForEachTable对我来说似乎有bug(即与IF语句不一致的行为),这可能是为什么它没有被MS记录的原因。
declare @LastObjectID int = 0
declare @TableName nvarchar(100) = ''
set @LastObjectID = (select top 1 [object_id] from sys.tables where [object_id] > @LastObjectID order by [object_id])
while(@LastObjectID is not null)
begin
set @TableName = (select top 1 [name] from sys.tables where [object_id] = @LastObjectID)
if(@TableName not in ('Profiles', 'ClientDetails', 'Addresses', 'AgentDetails', 'ChainCodes', 'VendorDetails'))
begin
exec('truncate table [' + @TableName + ']')
end
set @LastObjectID = (select top 1 [object_id] from sys.tables where [object_id] > @LastObjectID order by [object_id])
end
其他回答
只有当你的表之间没有任何外键关系时,才能截断所有的表,因为SQL Server不允许你用外键截断一个表。
另一种方法是先确定有外键的表并删除它们,然后再截断没有外键的表。
详见http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=65341和http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=72957。
当处理从具有外键关系的表中删除数据时(这基本上是任何设计良好的数据库的情况),我们可以禁用所有约束,删除所有数据,然后重新启用约束
-- disable all constraints
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"
-- delete data in all tables
EXEC sp_MSForEachTable "DELETE FROM ?"
-- enable all constraints
exec sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
这里有更多关于禁用约束和触发器的信息
如果某些表有标识列,我们可能需要重新播种它们
EXEC sp_MSForEachTable "DBCC CHECKIDENT ( '?', RESEED, 0)"
请注意,RESEED的行为在全新的表和之前从BOL中插入了一些数据的表之间有所不同:
DBCC CHECKIDENT ('table_name', RESEED, newReseedValue) The current identity value is set to the newReseedValue. If no rows have been inserted to the table since it was created, the first row inserted after executing DBCC CHECKIDENT will use newReseedValue as the identity. Otherwise, the next row inserted will use newReseedValue + 1. If the value of newReseedValue is less than the maximum value in the identity column, error message 2627 will be generated on subsequent references to the table.
感谢Robert指出禁用约束不允许使用截断的事实,约束必须被删除,然后重新创建
select 'delete from ' +TABLE_NAME from INFORMATION_SCHEMATABLE_TYPE='BASE TABLE'的表
结果就在那里。
在查询窗口复制粘贴并运行命令
虽然有点晚了,但也许能帮到别人。 我有时会创建一个过程,使用T-SQL执行以下操作:
将所有约束存储在临时表中 删除所有约束 除某些不需要截断的表外,截断所有表 重新创建所有约束。
我已经把它列在我的博客上了
我不明白为什么清除数据会比删除并重新创建每个表的脚本更好。
或者备份你的空数据库,并在旧的数据库上恢复它