我有一个数据库的测试环境,我想在测试周期开始时用新数据重新加载该数据库。我对重建整个数据库不感兴趣——只是简单地“重新设置”数据。
使用TSQL从所有表中删除所有数据的最佳方法是什么?是否有可以使用的系统存储过程、视图等?我不想为每个表手动创建和维护截断表语句-我更希望它是动态的。
我有一个数据库的测试环境,我想在测试周期开始时用新数据重新加载该数据库。我对重建整个数据库不感兴趣——只是简单地“重新设置”数据。
使用TSQL从所有表中删除所有数据的最佳方法是什么?是否有可以使用的系统存储过程、视图等?我不想为每个表手动创建和维护截断表语句-我更希望它是动态的。
当前回答
这是一种方法……可能还有其他10种更好/更有效的方法,但这听起来似乎很少有人这样做,所以下面是……
从sysobjects中获取一个表列表,然后用游标遍历这些表,为每次迭代调用sp_execsql('truncate table ' + @table_name)。
其他回答
select 'delete from ' +TABLE_NAME from INFORMATION_SCHEMATABLE_TYPE='BASE TABLE'的表
结果就在那里。
在查询窗口复制粘贴并运行命令
不要这样做!真的,这不是个好主意。
如果知道要截断哪些表,可以创建一个存储过程来截断它们。您可以修复顺序以避免外键问题。
如果您真的想要截断它们(例如,您可以BCP加载它们),那么您可以很快地删除数据库并从头创建一个新的数据库,这将带来额外的好处,即您可以确切地知道您所处的位置。
这是一种方法……可能还有其他10种更好/更有效的方法,但这听起来似乎很少有人这样做,所以下面是……
从sysobjects中获取一个表列表,然后用游标遍历这些表,为每次迭代调用sp_execsql('truncate table ' + @table_name)。
用脚本删除数据库要容易得多(甚至可能更快),然后直接从脚本中删除并创建数据库。
运行一次注释掉的部分,用希望截断的表填充_TruncateList表,然后运行脚本的其余部分。如果您经常这样做,_ScriptLog表将需要随着时间的推移被清理。
如果你想做所有的表,你可以修改这个,只要把SELECT name放入#TruncateList FROM sys.tables。然而,你通常不想做所有的事情。
此外,这将影响数据库中的所有外键,如果它对您的应用程序太生硬,您也可以修改它。这不是我的目的。
/*
CREATE TABLE _ScriptLog
(
ID Int NOT NULL Identity(1,1)
, DateAdded DateTime2 NOT NULL DEFAULT GetDate()
, Script NVarChar(4000) NOT NULL
)
CREATE UNIQUE CLUSTERED INDEX IX_ScriptLog_DateAdded_ID_U_C ON _ScriptLog
(
DateAdded
, ID
)
CREATE TABLE _TruncateList
(
TableName SysName PRIMARY KEY
)
*/
IF OBJECT_ID('TempDB..#DropFK') IS NOT NULL BEGIN
DROP TABLE #DropFK
END
IF OBJECT_ID('TempDB..#TruncateList') IS NOT NULL BEGIN
DROP TABLE #TruncateList
END
IF OBJECT_ID('TempDB..#CreateFK') IS NOT NULL BEGIN
DROP TABLE #CreateFK
END
SELECT Scripts = 'ALTER TABLE ' + '[' + OBJECT_NAME(f.parent_object_id)+ ']'+
' DROP CONSTRAINT ' + '[' + f.name + ']'
INTO #DropFK
FROM .sys.foreign_keys AS f
INNER JOIN .sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
SELECT TableName
INTO #TruncateList
FROM _TruncateList
SELECT Scripts = 'ALTER TABLE ' + const.parent_obj + '
ADD CONSTRAINT ' + const.const_name + ' FOREIGN KEY (
' + const.parent_col_csv + '
) REFERENCES ' + const.ref_obj + '(' + const.ref_col_csv + ')
'
INTO #CreateFK
FROM (
SELECT QUOTENAME(fk.NAME) AS [const_name]
,QUOTENAME(schParent.NAME) + '.' + QUOTENAME(OBJECT_name(fkc.parent_object_id)) AS [parent_obj]
,STUFF((
SELECT ',' + QUOTENAME(COL_NAME(fcP.parent_object_id, fcp.parent_column_id))
FROM sys.foreign_key_columns AS fcP
WHERE fcp.constraint_object_id = fk.object_id
FOR XML path('')
), 1, 1, '') AS [parent_col_csv]
,QUOTENAME(schRef.NAME) + '.' + QUOTENAME(OBJECT_NAME(fkc.referenced_object_id)) AS [ref_obj]
,STUFF((
SELECT ',' + QUOTENAME(COL_NAME(fcR.referenced_object_id, fcR.referenced_column_id))
FROM sys.foreign_key_columns AS fcR
WHERE fcR.constraint_object_id = fk.object_id
FOR XML path('')
), 1, 1, '') AS [ref_col_csv]
FROM sys.foreign_key_columns AS fkc
INNER JOIN sys.foreign_keys AS fk ON fk.object_id = fkc.constraint_object_id
INNER JOIN sys.objects AS oParent ON oParent.object_id = fkc.parent_object_id
INNER JOIN sys.schemas AS schParent ON schParent.schema_id = oParent.schema_id
INNER JOIN sys.objects AS oRef ON oRef.object_id = fkc.referenced_object_id
INNER JOIN sys.schemas AS schRef ON schRef.schema_id = oRef.schema_id
GROUP BY fkc.parent_object_id
,fkc.referenced_object_id
,fk.NAME
,fk.object_id
,schParent.NAME
,schRef.NAME
) AS const
ORDER BY const.const_name
INSERT INTO _ScriptLog (Script)
SELECT Scripts
FROM #CreateFK
DECLARE @Cmd NVarChar(4000)
, @TableName SysName
WHILE 0 < (SELECT Count(1) FROM #DropFK) BEGIN
SELECT TOP 1 @Cmd = Scripts
FROM #DropFK
EXEC (@Cmd)
DELETE #DropFK WHERE Scripts = @Cmd
END
WHILE 0 < (SELECT Count(1) FROM #TruncateList) BEGIN
SELECT TOP 1 @Cmd = N'TRUNCATE TABLE ' + TableName
, @TableName = TableName
FROM #TruncateList
EXEC (@Cmd)
DELETE #TruncateList WHERE TableName = @TableName
END
WHILE 0 < (SELECT Count(1) FROM #CreateFK) BEGIN
SELECT TOP 1 @Cmd = Scripts
FROM #CreateFK
EXEC (@Cmd)
DELETE #CreateFK WHERE Scripts = @Cmd
END