我需要清除许多表(最好是截断表)。但是表有许多FK约束。我试过这样的事,但失败了: -
ALTER TABLE Table1 NOCHECK CONSTRAINT ALL
TRUNCATE TABLE Table1
ALTER TABLE Table1 WITH CHECK CHECK CONSTRAINT ALL
这是我得到的错误: -
无法截断表'Test',因为它正被FOREIGN KEY约束引用。
请建议我暂时删除约束来删除或截断表格。
答案 0 :(得分:7)
只需按正确的FK顺序删除它们:
DELETE GreatGrandChild
DELETE Child
DELETE Parent
并且不要担心丢弃限制。
示例代码:
create table ParentTable (ParentID int primary key not null, RowValue varchar(10))
INSERT INTO ParentTable VALUES (1,'AAA')
INSERT INTO ParentTable VALUES (2,'BBB')
create table ChildTable (ChildID int primary key not null, ParentID int, RowValue varchar(10))
ALTER TABLE ChildTable ADD CONSTRAINT FK_ChildTable_ParentTable FOREIGN KEY
(ParentID) REFERENCES dbo.ParentTable (ParentID) ON UPDATE NO ACTION ON DELETE NO ACTION
INSERT INTO ChildTable VALUES (10,1,'a')
INSERT INTO ChildTable VALUES (11,1,'aa')
INSERT INTO ChildTable VALUES (12,2,'b')
INSERT INTO ChildTable VALUES (13,1,'aaa')
DELETE ChildTable
DELETE ParentTable
查找依赖于您的表的表运行此查询:
select
object_name(parent_object_id) AS ReferencesYourTable
,object_name(referenced_object_id) AS YourTable
,*
from sys.foreign_keys
WHERE object_name(referenced_object_id)='YourTable'
对于上述查询,删除在删除YourTable之前列出的每个表中的所有行。
答案 1 :(得分:4)
与其他人发布的内容相反,您永远不能截断外键引用的表。它在TRUNCATE TABLE下的联机丛书中有记录,但是自己尝试一下要快得多:
create table Parent (col1 int primary key)
create table Child (
col1 int primary key,
col2 int,
constraint fk foreign key (col2) references Parent (col1)
)
-- works
truncate table Child
-- doesn't work
truncate table Parent
alter table child nocheck constraint all
-- still doesn't work, even though the FK is disabled
truncate table Parent
drop table Child
drop table Parent
它不起作用的(概念)原因是TRUNCATE是物理操作,而不是逻辑操作。所以它不是'外键识别',如果你让它忽略外键,它会杀死参照完整性。
通常的解决方案(如其他人所述)是:
解决方案1
解决方案2
无论哪种解决方案都有效,这实际上是一个部署问题,哪个更容易,更适合您的情况。我知道你说这是一次性任务,但我仍然会编写脚本,即使只是作为一种学习经历。解决方案1在纯TSQL中很容易;解决方案2使用外部语言更容易。
答案 2 :(得分:0)
最简单的方法是删除约束,然后在截断后重新应用它们。
答案 3 :(得分:0)
您还需要在所有引用截断表的表中删除约束。之后,您将能够截断表格。但不要忘记再次创建它们。
即使引用截断表的所有表都没有行,MSSQL也不允许使用truncate table。
所以你需要首先删除FK约束。
答案 4 :(得分:0)
你需要做什么(可能有一个工具,但我不知道一个)是不可能的所有关系附加到受影响的表(来自和被截断的表)。这通常意味着禁用其他表的约束。
<SoapBox>
我确定你已经意识到了这一点,但是如果我没有指出这些限制可能存在于非常这个充分的理由,我将会失职,并且您需要非常,非常确定截断前后的数据都是干净的。<\SoapBox>
答案 5 :(得分:0)
最简单(也许不是最快)的方式是
DELETE FROM Table1
。
即使是外键也能正常工作(但是,删除顺序应该考虑在具有匹配主键的表之前删除具有外键的表。
答案 6 :(得分:0)
试试这个:
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
答案 7 :(得分:0)
您需要使用Table1的外键删除或截断任何表,或者如果您的数据库支持它,则执行级联删除(我认为它是在SQL Server 2005中添加的)
答案 8 :(得分:0)
如果您需要对数据库结构进行重大更改,则有三种选择。首先,您可以处理所有约束,删除然后在围绕您将采取的核心操作的脚本中重新创建它们。这是相当耗时且容易出错的。第二个选项是使用Enterprise Studio中的“设计”功能找到执行操作的方法。但是,在保存操作之前,只需右键单击设计窗口并要求保存为脚本。如果您希望在脚本中进行微调,这将为您提供一个起点。
您的最终选项 - 以及我更喜欢的选项 - 是使用第三方DDL生成器来更改数据库结构。我强烈推荐Red Gate的SQL比较。它也会生成一个脚本,但它可以很容易地比较两个数据库,以发现如何将一个数据库转换为另一个数据库。祝你好运!
答案 9 :(得分:0)
我在ETL系统中通过“记录”用户表中的每个外键以及CREATE和DROP脚本(当然都基于ALTER TABLE)来做了一些事情。对于您的情况,您将按指定的顺序循环它,并为每个表提取并执行所有“drop key”脚本,截断表,然后应用“create key”脚本。
一次性运行并没有真正帮助。它需要开发和认真调试(因为它 才能工作)。每次修改架构时,都可能需要更新此表的内容。但是,如果您将此过程作为常规程序的一部分,则值得付出努力。
选项2:通过所有目标表的SSMS生成“创建”脚本。删除所有表(以及所有数据)。运行脚本以重新创建空表。
答案 10 :(得分:0)
也试试这个。
暂时取消选中约束,然后重新检查。
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'
EXEC sp_MSForEachTable 'DELETE FROM ?'
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'
答案 11 :(得分:0)
使用delete statement
删除该表中的所有行后,使用以下命令从表名
删除*DBCC CHECKIDENT(tablename,RESEED,0)