database SQL 截断数据库?如何截断所有表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6028960/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SQL TRUNCATE DATABASE ? How to TRUNCATE ALL TABLES
提问by user609511
I use SQL server 2008 R2.
我使用 SQL Server 2008 R2。
Is there a SQL command to empty the database, instead of having to truncate all 20 my tables?
是否有 SQL 命令来清空数据库,而不必截断我的所有 20 个表?
I just want to delete the data not the structure.
我只想删除数据而不是结构。
回答by Mark S. Rasmussen
You can use the sp_MSforeachtable stored procedure like so:
您可以像这样使用 sp_MSforeachtable 存储过程:
USE MyDatabase
EXEC sp_MSforeachtable 'TRUNCATE TABLE ?'
Be warned that this will delete (by truncation) ALL data from all user tables. And in case you can't TRUNCATE due to foreign keys etc. you can run the same as a delete:
请注意,这将删除(通过截断)所有用户表中的所有数据。如果由于外键等原因无法 TRUNCATE,您可以像删除一样运行:
USE MyDatabase
EXEC sp_MSforeachtable 'DELETE FROM ?'
回答by Boycs
I use this script
我用这个脚本
EXEC sp_MSForEachTable ‘ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable ‘DELETE FROM ?'
EXEC sp_MSForEachTable ‘ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
回答by Chaitanya
The accepted answer doesn't quite work when you have foreign key relationships. In that case you have to drop the constraints and recreate them. Below is a stored proc for doing that based on the answer here
当您有外键关系时,接受的答案并不完全有效。在这种情况下,您必须删除约束并重新创建它们。以下是根据此处的答案执行此操作的存储过程
CREATE PROCEDURE [dbo].[deleteAllDataFromAllTables] AS
SET NOCOUNT ON
DECLARE @dropAndCreateConstraintsTable TABLE ( DropStmt varchar(max) , CreateStmt varchar(max) )
insert @dropAndCreateConstraintsTable select
DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema +
'].[' + ForeignKeys.ForeignTableName +
'] DROP CONSTRAINT [' + ForeignKeys.ForeignKeyName + ']; '
, CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema +
'].[' + ForeignKeys.ForeignTableName +
'] WITH CHECK ADD CONSTRAINT [' + ForeignKeys.ForeignKeyName +
'] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn +
']) REFERENCES [' + schema_name(sys.objects.schema_id) + '].[' +
sys.objects.[name] + ']([' +
sys.columns.[name] + ']); '
from sys.objects
inner join sys.columns
on (sys.columns.[object_id] = sys.objects.[object_id])
inner join (
select sys.foreign_keys.[name] as ForeignKeyName
,schema_name(sys.objects.schema_id) as ForeignTableSchema
,sys.objects.[name] as ForeignTableName
,sys.columns.[name] as ForeignTableColumn
,sys.foreign_keys.referenced_object_id as referenced_object_id
,sys.foreign_key_columns.referenced_column_id as referenced_column_id
from sys.foreign_keys
inner join sys.foreign_key_columns
on (sys.foreign_key_columns.constraint_object_id
= sys.foreign_keys.[object_id])
inner join sys.objects
on (sys.objects.[object_id]
= sys.foreign_keys.parent_object_id)
inner join sys.columns
on (sys.columns.[object_id]
= sys.objects.[object_id])
and (sys.columns.column_id
= sys.foreign_key_columns.parent_column_id)
) ForeignKeys
on (ForeignKeys.referenced_object_id = sys.objects.[object_id])
and (ForeignKeys.referenced_column_id = sys.columns.column_id)
where (sys.objects.[type] = 'U')
and (sys.objects.[name] not in ('sysdiagrams'))
DECLARE @DropStatement nvarchar(max)
DECLARE @RecreateStatement nvarchar(max)
DECLARE C1 CURSOR READ_ONLY
FOR
SELECT DropStmt from @dropAndCreateConstraintsTable
OPEN C1
FETCH NEXT FROM C1 INTO @DropStatement
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing ' + @DropStatement
execute sp_executesql @DropStatement
FETCH NEXT FROM C1 INTO @DropStatement
END
CLOSE C1
DEALLOCATE C1
DECLARE @DeleteTableStatement nvarchar(max)
DECLARE C2 CURSOR READ_ONLY
FOR
SELECT 'Delete From [dbo].[' + TABLE_NAME + ']' from INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbo' -- Change your schema appropriately.
OPEN C2
FETCH NEXT FROM C2 INTO @DeleteTableStatement
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing ' + @DeleteTableStatement
execute sp_executesql @DeleteTableStatement
FETCH NEXT FROM C2 INTO @DeleteTableStatement
END
CLOSE C2
DEALLOCATE C2
DECLARE C3 CURSOR READ_ONLY
FOR
SELECT CreateStmt from @dropAndCreateConstraintsTable
OPEN C3
FETCH NEXT FROM C3 INTO @RecreateStatement
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing ' + @RecreateStatement
execute sp_executesql @RecreateStatement
FETCH NEXT FROM C3 INTO @RecreateStatement
END
CLOSE C3
DEALLOCATE C3
GO
回答by Dave Bennett
Most of the solutions provided either don't use TRUNCATE, which is different from DELETE, or they don't deal with the issue of foreign key constraints. The solution provided by Chaitanya comes close, but it falls back to using DELETE, and it does it in a stored procedure, which seems to not fit a situation where you are nuking all data in a database.
提供的大多数解决方案要么不使用与 DELETE 不同的 TRUNCATE,要么不处理外键约束问题。Chaitanya 提供的解决方案很接近,但它回退到使用 DELETE,并且它在存储过程中执行,这似乎不适合您将数据库中的所有数据核对的情况。
So, below is my variation which does use TRUNCATE and does address the foreign key constraint problem.
所以,下面是我的变体,它确实使用了 TRUNCATE 并解决了外键约束问题。
/* TRUNCATE ALL TABLES IN A DATABASE */
DECLARE @dropAndCreateConstraintsTable TABLE
(
DropStmt VARCHAR(MAX)
,CreateStmt VARCHAR(MAX)
)
/* Gather information to drop and then recreate the current foreign key constraints */
INSERT @dropAndCreateConstraintsTable
SELECT DropStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema
+ '].[' + ForeignKeys.ForeignTableName + '] DROP CONSTRAINT ['
+ ForeignKeys.ForeignKeyName + ']; '
,CreateStmt = 'ALTER TABLE [' + ForeignKeys.ForeignTableSchema
+ '].[' + ForeignKeys.ForeignTableName
+ '] WITH CHECK ADD CONSTRAINT [' + ForeignKeys.ForeignKeyName
+ '] FOREIGN KEY([' + ForeignKeys.ForeignTableColumn
+ ']) REFERENCES [' + SCHEMA_NAME(sys.objects.schema_id)
+ '].[' + sys.objects.[name] + ']([' + sys.columns.[name]
+ ']); '
FROM sys.objects
INNER JOIN sys.columns
ON ( sys.columns.[object_id] = sys.objects.[object_id] )
INNER JOIN ( SELECT sys.foreign_keys.[name] AS ForeignKeyName
,SCHEMA_NAME(sys.objects.schema_id) AS ForeignTableSchema
,sys.objects.[name] AS ForeignTableName
,sys.columns.[name] AS ForeignTableColumn
,sys.foreign_keys.referenced_object_id AS referenced_object_id
,sys.foreign_key_columns.referenced_column_id AS referenced_column_id
FROM sys.foreign_keys
INNER JOIN sys.foreign_key_columns
ON ( sys.foreign_key_columns.constraint_object_id = sys.foreign_keys.[object_id] )
INNER JOIN sys.objects
ON ( sys.objects.[object_id] = sys.foreign_keys.parent_object_id )
INNER JOIN sys.columns
ON ( sys.columns.[object_id] = sys.objects.[object_id] )
AND ( sys.columns.column_id = sys.foreign_key_columns.parent_column_id )
) ForeignKeys
ON ( ForeignKeys.referenced_object_id = sys.objects.[object_id] )
AND ( ForeignKeys.referenced_column_id = sys.columns.column_id )
WHERE ( sys.objects.[type] = 'U' )
AND ( sys.objects.[name] NOT IN ( 'sysdiagrams' ) )
/* SELECT * FROM @dropAndCreateConstraintsTable AS DACCT */
DECLARE @DropStatement NVARCHAR(MAX)
DECLARE @RecreateStatement NVARCHAR(MAX)
/* Drop Constraints */
DECLARE C1 CURSOR READ_ONLY
FOR
SELECT DropStmt
FROM @dropAndCreateConstraintsTable
OPEN C1
FETCH NEXT FROM C1 INTO @DropStatement
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing ' + @DropStatement
EXECUTE sp_executesql @DropStatement
FETCH NEXT FROM C1 INTO @DropStatement
END
CLOSE C1
DEALLOCATE C1
/* Truncate all tables in the database in the dbo schema */
DECLARE @DeleteTableStatement NVARCHAR(MAX)
DECLARE C2 CURSOR READ_ONLY
FOR
SELECT 'TRUNCATE TABLE [dbo].[' + TABLE_NAME + ']'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_TYPE = 'BASE TABLE'
/* Change your schema appropriately if you don't want to use dbo */
OPEN C2
FETCH NEXT FROM C2 INTO @DeleteTableStatement
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing ' + @DeleteTableStatement
EXECUTE sp_executesql @DeleteTableStatement
FETCH NEXT FROM C2 INTO @DeleteTableStatement
END
CLOSE C2
DEALLOCATE C2
/* Recreate foreign key constraints */
DECLARE C3 CURSOR READ_ONLY
FOR
SELECT CreateStmt
FROM @dropAndCreateConstraintsTable
OPEN C3
FETCH NEXT FROM C3 INTO @RecreateStatement
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Executing ' + @RecreateStatement
EXECUTE sp_executesql @RecreateStatement
FETCH NEXT FROM C3 INTO @RecreateStatement
END
CLOSE C3
DEALLOCATE C3
GO
回答by Rashad Annara
execute this
执行这个
EXEC sp_MSforeachtable 'PRINT ''ALTER TABLE ? NOCHECK CONSTRAINT ALL'''
EXEC sp_MSforeachtable 'print ''DELETE FROM ?'''
EXEC sp_MSforeachtable 'print ''ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all'''
After copy the printed result and paste it on Query field and Execute it. It will truncate all tables.
复制打印的结果并将其粘贴到查询字段并执行后。它将截断所有表。
回答by Varun Rathore
No nonsense script this:
没有废话脚本:
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
EXEC sp_MSforeachtable 'DBCC CHECKIDENT ( ''?'', RESEED, 0)'
GO
Truncate will still not work if you have foreign keys in tables. This script will reset all identity columns as well.
如果表中有外键,截断仍然不起作用。此脚本还将重置所有标识列。
回答by user3226298
DECLARE @nombre NVARCHAR(100)
DECLARE @tablas TABLE(nombre nvarchar(100))
INSERT INTO @tablas
SELECT t.TABLE_SCHEMA+ '.'+t.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES T
DECLARE @contador INT=0
SELECT @contador=COUNT(*) FROM INFORMATION_SCHEMA.TABLES
WHILE @contador>0
BEGIN
SELECT TOP 1 @nombre=nombre FROM @tablas
DECLARE @sql NVARCHAR(500)=''
SET @sql =@sql+'Truncate table '+@nombre
EXEC (@sql)
SELECT @sql
SET @contador=@contador-1
DELETE TOP (1) @tablas
END
回答by Sathish
---- Remove Constraint ----
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"
---- Delete Data ----
EXEC sp_MSForEachTable "DELETE FROM ?"
---- Add Constraint ----
EXEC sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
---- Reset Identity value ----
EXEC sp_MSForEachTable "DBCC CHECKIDENT ( '?', RESEED, 0)"
回答by Matthew Fritz
Taking a point from both Boycs Answer and mtmurdock's subsequent answer I have the following stored proc on all of my development or staging databases. I've added some switches to fit my own requirement if I need to add in statements to reseed the data for certain columns.
从 Boycs Answer 和 mtmurdock 的后续答案中得出一个观点,我在我的所有开发或暂存数据库中都有以下存储过程。如果我需要添加语句来为某些列重新设定数据,我已经添加了一些开关来满足我自己的要求。
(Note:I would have added this as a comment to Boycs brilliant answer but I haven't got enough reputation to do that yet. So please accept my apologies for adding this as an entirely new answer.)
(注意:我会将此添加为对 Boycs 出色答案的评论,但我还没有足够的声誉来做到这一点。所以请接受我的歉意,将其添加为一个全新的答案。)
ALTER PROCEDURE up_ResetEntireDatabase
@IncludeIdentReseed BIT,
@IncludeDataReseed BIT
AS
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
IF @IncludeIdentReseed = 1
BEGIN
EXEC sp_MSForEachTable 'DBCC CHECKIDENT (''?'' , RESEED, 1)'
END
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
IF @IncludeDataReseed = 1
BEGIN
-- Populate Core Data Table Here
END
GO
And then once ready the execution is really simple:
然后一旦准备好执行就非常简单:
EXEC up_ResetEntireDatabase 1, 1
回答by Ben
You can also use this stored procedure if you only want to truncate all tables in a specific schema:
如果您只想截断特定架构中的所有表,也可以使用此存储过程:
-- =============================================
-- Author: Ben de Ridder
-- Create date: 20160513
-- Description: Truncate all tables in schema
-- =============================================
CREATE PROCEDURE TruncateAllTablesInSchema
@schema nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @table nVARCHAR(255)
DECLARE db_cursor CURSOR FOR
select t.name
from sys.tables t inner join
sys.schemas s on
t.schema_id=s.schema_id
where s.name=@schema
order by 1
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @table
WHILE @@FETCH_STATUS = 0
BEGIN
declare @sql nvarchar(1000)
set @sql = 'truncate table [' + @schema + '].[' + @table + ']'
exec sp_sqlexec @sql
FETCH NEXT FROM db_cursor INTO @table
END
CLOSE db_cursor
DEALLOCATE db_cursor
END
GO

