我有一个数据库的测试环境,我想在测试周期开始时用新数据重新加载.我对重建整个数据库不感兴趣 - 只需简单地"重新设置"数据.
使用TSQL从所有表中删除所有数据的最佳方法是什么?是否有可以使用的系统存储过程,视图等?我不想为每个表手动创建和维护truncate table语句 - 我希望它是动态的.
当处理从具有外键关系的表中删除数据时 - 基本上是任何设计合理的数据库的情况 - 我们可以禁用所有约束,删除所有数据然后重新启用约束
-- 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)
当前标识值设置为newReseedValue.如果自创建表以来没有向表插入任何行,则在执行DBCC CHECKIDENT后插入的第一行将使用newReseedValue作为标识.否则,插入的下一行将使用newReseedValue + 1.如果newReseedValue的值小于标识列中的最大值,则将在对该表的后续引用上生成错误消息2627.
感谢Robert指出禁用约束不允许使用truncate的事实,必须删除约束,然后重新创建
对于SQL 2005,
EXEC sp_MSForEachTable 'TRUNCATE TABLE ?'
结合2000和2005/2008的更多链接..
这是数据库擦除脚本的国王.它将清除所有表并正确重新设置它们:
SET QUOTED_IDENTIFIER ON; EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? NOCHECK CONSTRAINT ALL' EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? DISABLE TRIGGER ALL' EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?' EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? CHECK CONSTRAINT ALL' EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? ENABLE TRIGGER ALL' EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON'; IF NOT EXISTS ( SELECT * FROM SYS.IDENTITY_COLUMNS JOIN SYS.TABLES ON SYS.IDENTITY_COLUMNS.Object_ID = SYS.TABLES.Object_ID WHERE SYS.TABLES.Object_ID = OBJECT_ID('?') AND SYS.IDENTITY_COLUMNS.Last_Value IS NULL ) AND OBJECTPROPERTY( OBJECT_ID('?'), 'TableHasIdentity' ) = 1 DBCC CHECKIDENT ('?', RESEED, 0) WITH NO_INFOMSGS;
享受,但要小心!
最简单的方法是
打开SQL Management Studio
导航到您的数据库
右键单击并选择Tasks-> Generate Scripts(pic 1)
在"选择对象"屏幕上,选择"选择特定对象"选项并选中"表格"(图2)
在下一个屏幕上,选择"高级",然后将"脚本删除和创建"选项更改为"脚本删除和创建"(图3)
选择将脚本保存到新的编辑器窗口或文件,然后根据需要运行.
这将为您提供一个脚本,可以删除并重新创建所有表,而无需担心调试或是否包含所有内容.虽然这不仅仅是截断,但结果是相同的.请记住,自动递增主键将从0开始,而截断表将记住最后分配的值.如果您无法访问PreProd或Production环境中的Management studio,也可以从代码执行此操作.
1.
2.
3.
截断所有表只有在表之间没有任何外键关系时才会起作用,因为SQL Server不允许您使用外键截断表.
另一种方法是使用外键确定表并从中删除,然后可以在没有外键的情况下截断表.
有关详细信息,请参阅http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=65341和http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=72957.
我喜欢与MSSQL Server Deveploper或Enterprise一起使用的另一种选择是在创建空模式后立即创建数据库的快照.此时,您可以继续将数据库还原到快照.
不要这样做!真的,不是一个好主意.
如果您知道要截断哪些表,请创建一个截断它们的存储过程.您可以修复订单以避免外键问题.
如果你真的想要截断它们(例如你可以BCP加载它们),那么你可以快速删除数据库并从头开始创建一个新的数据库,这将带来额外的好处,你可以确切地知道它在哪里.