在SQL Server中启用所有可能的约束

时间:2014-09-24 13:15:43

标签: sql sql-server

最近我不得不迁移数据。为此,我使用此命令禁用了所有约束

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

我已将旧数据库中的所有数据迁移到新数据库。现在我面临一些数据冲突,不允许我重新启用所有约束。我试过这个命令,但它对我不起作用

EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"

有没有办法在没有数据冲突的情况下启用所有外键关系? 请告诉我执行此任务的查询。

注意: 我有大约20个表,它们之间存在冲突的数据。我不想对它们启用约束。 我只想对其他没有问题的表(大约200个表)启用约束。

2 个答案:

答案 0 :(得分:1)

我认为这不可能自动完成(但我错了:))。 运行EXEC sp_msforeachtable时,这实际上是针对每个表单独运行的,这意味着不会应用检查约束与现有数据冲突的约束(并且您会看到这些表中的错误)

所以我的想法是在所有表中执行一次所有约束的启用,然后查看哪些表仍存在无法激活的约束。 (在这些表格中我们也将停用其他约束......)

here我得到了这个好东西:

SELECT name, tbl = object_name(parent_obj)
FROM sysobjects
WHERE objectproperty(id, 'CnstIsDisabled') = 1

现在,您将获得所有禁用的约束和表名。 执行EXEC sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"后,对它们有一些约束错误的表应显示在此查询中(但可能多次,因为可能有多个约束在同一个表上失败)。

你可以进一步修改

SELECT DISTINCT tbl = object_name(parent_obj), 'EXEC sp_msforeachtable "ALTER TABLE ' + object_name(parent_obj) + ' NOCHECK CONSTRAINT all"'
FROM sysobjects
WHERE objectproperty(id, 'CnstIsDisabled') = 1

现在你在最后一列中得到了可执行语句,你应该只能选择最后一列的所有行并执行,那么你应该只在那些可以激活所有约束的表上激活约束。

答案 1 :(得分:0)

这无论如何都不是一个理想的解决方案......但是如果你想要一个快速而肮脏的方式来系统地浏览所有表并尝试启用约束,那么我将如何做到这一点:

编写程序为您执行此操作。

运行此查询以获取所有表名的列表:

selectTABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' 

foreach TABLE_NAME 
{
    try{
        ALTER TABLE TABLE_NAME CHECK CONSTRAINT ALL
    }
    catch{}
}

更好的解决方案是修复表中无法启用此功能的数据,并在所有表中启用它。我建议在部分启用时这样做。