某人必須已經編寫了腳本才能從數據庫的所有表中刪除所有行。 使用DELETE命令不是一個選項,因爲它可能會在大型表上花費時間。 當然,在stackoverflow和其他地方有很多例子,但是它們不適用於使用外鍵的表。從數據庫的所有表中刪除所有行
基本上,腳本應該這樣做:
- 存儲所有外鍵定義在臨時表
- 刪除所有外鍵
- 截斷所有表
- 恢復外鍵
我想我有:
IF OBJECT_ID('tempdb..#ForeignKeys') IS NOT NULL
DROP TABLE #ForeignKeys;
WITH ForeignKeys AS (
SELECT
QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name) AS ParentTable
, QUOTENAME(SCHEMA_NAME(rt.schema_id)) + '.' + QUOTENAME(rt.name) AS ReferenceTable
, QUOTENAME(f.name) AS ConstraintName
, STUFF(Parent.Cols, 1, 1, '') AS ParentColumns
, STUFF(Reference.Cols, 1, 1, '') AS ReferenceColumns
, REPLACE(f.update_referential_action_desc, '_', ' ') AS UpdateAction
, REPLACE(f.delete_referential_action_desc, '_', ' ') AS DeleteAction
FROM
sys.tables AS t
LEFT JOIN sys.foreign_keys AS f
ON f.parent_object_id = t.object_id
AND f.type = 'F'
LEFT JOIN sys.tables AS rt
ON f.referenced_object_id = rt.object_id
CROSS APPLY
(
SELECT
',' + QUOTENAME(COL_NAME(fc.parent_object_id, fc.parent_column_id))AS [text()]
FROM
sys.foreign_key_columns AS fc
WHERE
fc.constraint_object_id = f.object_id
ORDER BY
fc.constraint_column_id
FOR XML PATH('')
) Parent(Cols)
CROSS APPLY
(
SELECT
',' + QUOTENAME(COL_NAME(fc.referenced_object_id, fc.referenced_column_id)) AS [text()]
FROM
sys.foreign_key_columns AS fc
WHERE
fc.constraint_object_id = f.object_id
ORDER BY
fc.constraint_column_id
FOR XML PATH('')
) Reference(Cols)
)
SELECT
ParentTable AS TableName
, 'ALTER TABLE ' + ParentTable + ' DROP CONSTRAINT ' + ConstraintName AS DropCmd
, 'TRUNCATE TABLE ' + ParentTable AS TruncateCmd
, 'ALTER TABLE ' + ParentTable + ' ADD CONSTRAINT ' + ConstraintName + ' FOREIGN KEY('
+ ParentColumns + ') REFERENCES ' + ReferenceTable + ' (' + ReferenceColumns
+ ') ON UPDATE ' + UpdateAction
+ ' ON DELETE ' + DeleteAction COLLATE SQL_Latin1_General_CP1_CI_AS AS CreateCmd
INTO
#ForeignKeys
FROM
ForeignKeys
ORDER BY
1;
-- SELECT * FROM #ForeignKeys
DECLARE @TableName SYSNAME
DECLARE @Sql NVARCHAR(MAX)
-- Drop all constraints
DECLARE FkCursor CURSOR FOR
SELECT
TableName
, DropCmd
FROM
#ForeignKeys
WHERE
DropCmd IS NOT NULL
OPEN FkCursor
FETCH NEXT FROM FkCursor INTO @TableName, @Sql
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @TableName + ' : ' + @sql
EXEC sp_executesql @Sql
FETCH NEXT FROM FkCursor INTO @TableName, @Sql
END
CLOSE FkCursor
DEALLOCATE FkCursor
-- Truncate all tables
DECLARE FkCursor CURSOR FOR
SELECT
TableName
, TruncateCmd
FROM
#ForeignKeys
OPEN FkCursor
FETCH NEXT FROM FkCursor INTO @TableName, @Sql
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @TableName + ' : ' + @sql
EXEC sp_executesql @Sql
FETCH NEXT FROM FkCursor INTO @TableName, @Sql
END
CLOSE FkCursor
DEALLOCATE FkCursor
-- Create all foreign keys
DECLARE FkCursor CURSOR FOR
SELECT
TableName
, CreateCmd
FROM
#ForeignKeys
WHERE
CreateCmd IS NOT NULL
OPEN FkCursor
FETCH NEXT FROM FkCursor INTO @TableName, @Sql
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @TableName + ' : ' + @sql
EXEC sp_executesql @Sql
FETCH NEXT FROM FkCursor INTO @TableName, @Sql
END
CLOSE FkCursor
DEALLOCATE FkCursor
DROP TABLE #ForeignKeys;
到目前爲止你寫了些什麼? – rvphx 2012-04-17 15:32:43
如果您有所有表的創建腳本,爲什麼不刪除所有表(或數據庫),然後重新運行創建腳本? – 2012-04-17 15:33:17
刪除對FK引用的表格不起作用。對於你沒有被FK引用的表,然後轉向。定義年齡。我有超過100 GB的數據庫,我有一個腳本清除所有行使用截斷和刪除像20分鐘。 – Paparazzi 2012-04-17 15:55:29