使用DTS导入/导出向导导入数据时如何处理FK约束?


16

我正在尝试使用SQL Server导入和导出向导将数据从生产数据库复制到开发数据库,​​但是当我这样做时失败,并显示错误“ INSERT语句与FOREIGN KEY约束冲突”,我有40多个表FK约束,是否有一些简单的方法可以解决此问题,而无需编写放置约束/添加constrat脚本?

编辑:我刚刚发现,在我正在运行的Web版本的SQL Server中,DTS不允许您保存软件包。

Answers:


28

我在SQLTeam.com上获得了以下解决方案:

采用:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

然后导入您的数据

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

使用该方法,我可以毫无问题地导入所有数据。


1
sp_msforeachtable(和sp_MSForEachDb)未记录且不受支持。您不应该/避免使用它。它可能会跳过表!请参阅来自@AaronBertrand的帖子-> sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/……和此连接项-(MS表示他们不会修复)-> connect.microsoft.com/SQLServer / feedback / details / 264677 /…
Kin Shah

在经过数小时的努力以克服数据输出的FK约束之后,对我来说,它的工作非常完美。
levininja 2015年

在Azure SQL V12上运行时,出现错误“找不到存储过程'sp_msforeachtable'”。

无论如何都不起作用:/
Douglas Gaskell

您是救命的人
CanŞahinBakır19年

5

我从我无法控制的服务器上在机器上生成了数据库的精确副本。

我是个笨蛋,但这是我做的:

  1. 从源代码控制中的脚本创建数据库(提示,提示!)。如果没有该脚本,则始终可以通过该Tasks选项从现有数据库中生成它。

  2. 如果在创建时将任何数据自动插入到YourDB中,请运行DELETE FROM YourDB.dbo.tblYourTable

    • 如果存在外键,则无法截断数据,因此必须使用DELETE
  3. 在目标服务器上运行此命令: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. 右键单击YourDBObject Explorer。点击Tasks->Import Data...

  5. 向导的前几个屏幕不言自明。

  6. Select Source Table and Views向导的屏幕上,单击要复制的每个表旁边的复选框。

  7. 对于该屏幕上的每一行(表),单击它,使其突出显示,然后单击Edit Mappings

  8. 对于每一行(表),单击/选中Append rows to the destination tableEnable identity insert

    • 如果您单击Delete rows in destination table它会失败,因为它没有发出DELETE命令,它发出的TRUNCATE命令仍然与我们的外键冲突,因为TRUNCATE它不受NOCHECK CONSTRAINT早期版本的约束。
  9. 单击向导的其余部分,然后单击确定Finish

  10. 注意错误 ; 警告可能可以忽略。

    • 如果有错误,请单击Report按钮并查看报告。尝试和苏斯什么是SuccessErrorStopped。您可能需要修复埋在该报告中某个地方的错误的根本原因。然后,您可能需要执行DELETE FROM YourDB.dbo.theErrorTable。现在,单击导入向导上的“后退”按钮,然后取消选中所有为的表Success。无限重复广告。
  11. 在目标服务器上运行此命令: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • 如果有错误,...我不知道,但是请修复它们,然后重试!
  12. 好极了!:)

感谢所有回答这个问题以及SE网络上与此类似的问题的人,以帮助我解决这个问题。


您是救生员
Tom Gullen

1
非常感谢您,在损坏的驱动器上进行了备份,无法将数据库复制到任何地方(I / O错误)。以此方式一次将数据导入几个表可帮助我恢复99%的数据。
Tom Gullen

1
你摇滚!另一个帮助我的命令:EXEC sp_msforeachtable'delete from?'; 如果发生错误,则删除所有内容。sp_msforeachtable脚本在此处gist.githubusercontent.com/metaskills/893599/raw/…–
Sanchitos,

4

在导入向导中,您可以先删除行,如果有身份字段,则可以启用身份插入,如下所示

在此处输入图片说明

如果要禁用检查约束,则在向导要求您保存程序包时,将其保存,然后按如下所示编辑连接管理器:

在此处输入图片说明

注意:如果定义了外键,则无法截断表。


3

不要放弃约束。

您应该做的是保存向导创建的SSIS包,然后在BIDS / SSDT中对其进行编辑。编辑包时,您将能够控制处理表的顺序,因此您可以处理父表,然后在完成所有父表后再处理子表。


3
那也不是很有效,现在需要花费将近一个小时来修改软件包,以确保一切都以正确的顺序进行,即使那样我也不能确定。随着数据库的增长,每次这样做都会增加麻烦,不用了,谢谢。必须有一种简单的方法来执行此操作。

1

这样的问题向我们表明,制造SQL Server的人们从未真正使用过他们的产品。这是如此明显的遗漏,以至于人们不得不怀疑他们只是忘记正确地做些什么(我已经列出了大约30个其他类似的令人困扰的问题,我必须克服这些问题才能像其他DB所做的那样进行这项工作。盒子;包括我们首先需要一个糟糕的向导来进行此操作的事实[如果我有时间等待该向导为每个数据库连接并枚举相同表, ...我有时间度过一个愉快的假期])。

我很懒,不想打字 EXEC sp_msforeachtable ...每次我这样做两次。我的解决方法是将约束保留在生产服务器上,并将其从开发服务器中删除。这样可以避免错误,但是这种方法确实有一些非常大的副作用。首先,您将无法再将完整备份还原到您的开发服务器(除非您可以再次删除它们)。其次,当您确定数据的使用者也强制执行这些约束(或不关心它们)时,此方法最有效。以我为例,我们只有一个消费者(我们的网站),因此我们也将这些约束内置到站点代码中(即,在删除用户记录之前,我们先删除该用户的所有电话记录)。是,这从根本上消除了对约束的需求,并使我需要做的工作加倍,但同时也使我有机会验证我的代码在有或没有基于DBMS的约束下都可以工作(事实是它们仍然在生产环境中。服务器仅作为应急计划)。您可以在我的设计中称其为缺陷,但我宁愿称其为有缺陷的DBMS的解​​决方法。无论如何,与在MSSQL内部相比,在其他任何地方执行此操作仍然更快,更容易,因为它无法应对自己的设计。


0

我认为您无法从生产服务器执行备份和还原,因为这是至关重要的数据。如果没有适当的权利,它将变得更加复杂。但是,如果您具有db backup n restore权限,则可以执行它。

否则,我建议的一种方法是删除所有约束和索引,然后在导入或导出数据后再次添加它们。

没有确切的答案,但处理速度很快。


谢谢,但是我明确地说我不想编写掉落/创建约束脚本。

0

只需阅读该主题即可。这是一篇旧文章,但这是我为帮助将来的人们阅读本文所做的。

就我而言,我想导入一个空的相同表。编辑映射时,我选择<ignore>主键。我所有的内容都会被自动很好地添加。

希望它能帮助某人


1
忽略主键对外键有帮助吗?
dezso 2015年

就我而言,是的,因为我实际上是在复制表格。所以我以相同的主键结束。因此,指向我的表的外键仍然对应于正确的条目
Greg
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.