使用MSSQL2005,如果我首先截断子表(具有FK关系的主键的表),我可以截断带有外键约束的表吗?
我知道我也可以
使用不带where子句的DELETE,然后RESEED标识(或) 删除FK,截断表,并重新创建FK。
我认为只要我在父表之前截断子表,我就可以不做上面的任何一个选项,但我得到了这个错误:
不能截断表'TableName',因为它被一个FOREIGN KEY约束引用。
使用MSSQL2005,如果我首先截断子表(具有FK关系的主键的表),我可以截断带有外键约束的表吗?
我知道我也可以
使用不带where子句的DELETE,然后RESEED标识(或) 删除FK,截断表,并重新创建FK。
我认为只要我在父表之前截断子表,我就可以不做上面的任何一个选项,但我得到了这个错误:
不能截断表'TableName',因为它被一个FOREIGN KEY约束引用。
当前回答
唯一的方法是在截断之前删除外键。截断数据之后,必须重新创建索引。
下面的脚本生成删除所有外键约束所需的SQL。
DECLARE @drop NVARCHAR(MAX) = N'';
SELECT @drop += N'
ALTER TABLE ' + QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name)
+ ' DROP CONSTRAINT ' + QUOTENAME(fk.name) + ';'
FROM sys.foreign_keys AS fk
INNER JOIN sys.tables AS ct
ON fk.parent_object_id = ct.[object_id]
INNER JOIN sys.schemas AS cs
ON ct.[schema_id] = cs.[schema_id];
SELECT @drop
接下来,下面的脚本生成重新创建外键所需的SQL。
DECLARE @create NVARCHAR(MAX) = N'';
SELECT @create += N'
ALTER TABLE '
+ QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name)
+ ' ADD CONSTRAINT ' + QUOTENAME(fk.name)
+ ' FOREIGN KEY (' + STUFF((SELECT ',' + QUOTENAME(c.name)
-- get all the columns in the constraint table
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.parent_column_id = c.column_id
AND fkc.parent_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'')
+ ') REFERENCES ' + QUOTENAME(rs.name) + '.' + QUOTENAME(rt.name)
+ '(' + STUFF((SELECT ',' + QUOTENAME(c.name)
-- get all the referenced columns
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.referenced_column_id = c.column_id
AND fkc.referenced_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'') + ');'
FROM sys.foreign_keys AS fk
INNER JOIN sys.tables AS rt -- referenced table
ON fk.referenced_object_id = rt.[object_id]
INNER JOIN sys.schemas AS rs
ON rt.[schema_id] = rs.[schema_id]
INNER JOIN sys.tables AS ct -- constraint table
ON fk.parent_object_id = ct.[object_id]
INNER JOIN sys.schemas AS cs
ON ct.[schema_id] = cs.[schema_id]
WHERE rt.is_ms_shipped = 0 AND ct.is_ms_shipped = 0;
SELECT @create
运行生成的脚本删除所有外键,截断表,然后运行生成的脚本重新创建所有外键。
查询从这里开始。
其他回答
DELETE FROM TABLENAME
DBCC CHECKIDENT ('DATABASENAME.dbo.TABLENAME', RESEED, 0)
注意,如果您有数百万条以上的记录,这可能不是您想要的,因为它非常慢。
正确的;你不能截断一个有FK约束的表。
通常我的处理方法是:
去掉约束 截断表格 重新创建约束。
(当然,这一切都在一笔交易中。)
当然,这只适用于子节点已经被截断的情况。否则,我会走不同的路线,完全取决于我的数据是什么样子的。(变量太多,不便在此赘述。)
最初的海报决定了为什么会这样;更多细节请看这个答案。
这是一个使用实体框架的人的例子
要重置的表:Foo 另一个表取决于:酒吧 约束表Foo上的列:FooColumn 表Bar上的约束列:BarColumn 公共覆盖无效Down() { DropForeignKey(“dbo。Bar", "BarColumn", "dbo.Foo"); Sql("TRUNCATE TABLE Foo"); AddForeignKey(“dbo。Bar", "BarColumn", "dbo "。Foo", "FooColumn", cascadeDelete: true); }
如果您以任何频率执行此操作,甚至在时间表上,我绝对不会明确地使用DML语句。写入事务日志的成本非常高,将整个数据库设置为SIMPLE恢复模式以截断一个表是荒谬的。
最好的办法,不幸是艰苦或费力的办法。这是:
减少约束 截断表 重新创建约束
我这样做的过程包括以下步骤:
在SSMS中,右键单击有问题的表,并选择查看依赖项 记下引用的表格(如果有的话) 回到对象资源管理器,展开Keys节点并记下外键(如果有的话) 开始编写脚本(删除/截断/重新创建)
这种性质的脚本应该在begin tran和commit tran块中完成。
最简单的方法: 1 -在phpmyadmin中输入 2 -点击左列的表名 3 -点击操作(顶部菜单) 4 -点击“清空表格(TRUNCATE)” 5 -禁用框“启用外键检查” 6 -完成!
图片教程链接 教程:http://www.imageno.com/wz6gv1wuqajrpic.html (对不起,我没有足够的声誉上传图片:P)