无法在数据库中启用所有禁用的约束

时间:2014-07-16 15:01:14

标签: sql sql-server sql-server-2008

此处的最终目标是重新启用数据库中的所有约束。

这里有关于发生的事情的一些背景知识。我是一个SQL Server数据库的SQL脚本,它将一堆记录添加到多个表中。我已经禁用了数据库中许多表的外键约束,以便将这些语句插入到我想要的表中。所以我在脚本的开头用这个语句来做。

EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all";

它禁用了我的所有约束,一切都很好。一切都放在表中没有错误。然后我使用此命令再次启用所有约束。

exec sp_msforeachtable @command1="print '?'", 
                       @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all";

这是错误发生的地方。我在控制台中得到了这个:

  

ALTER TABLE语句与FOREIGN KEY约束冲突" FK__PW_COLUMN__TABLE__3864608B"。冲突发生在数据库" PWTechDocs",table" dbo.PW_TABLES",column' TABLE_NAME'。

它表示约束FK__PW_COLUMN__TABLE__3864608B在表PW_TABLES中,因此我运行此语句以禁用它,同时启用所有其他约束。

ALTER TABLE PW_TABLES NOCHECK CONSTRAINT FK__PW_COLUMN__TABLE__3B40CD36;

然后在运行上述语句时出现此错误:

  

约束' FK__PW_COLUMN__TABLE__3B40CD36'不属于表格' PW_TABLES'。

我尝试在其他表中运行相同的东西,但约束不在哪里可以找到。如何再次启用数据库中的所有约束?

2 个答案:

答案 0 :(得分:0)

您可以使用以下方法找到约束:

SELECT  obj.name AS FK_NAME,
    sch.name AS [schema_name],
    tab1.name AS [table],
    col1.name AS [column],
    tab2.name AS [referenced_table],
    col2.name AS [referenced_column]
FROM sys.foreign_key_columns fkc
INNER JOIN sys.objects obj
    ON obj.object_id = fkc.constraint_object_id
INNER JOIN sys.tables tab1
    ON tab1.object_id = fkc.parent_object_id
INNER JOIN sys.schemas sch
    ON tab1.schema_id = sch.schema_id
INNER JOIN sys.columns col1
    ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
INNER JOIN sys.tables tab2
    ON tab2.object_id = fkc.referenced_object_id
INNER JOIN sys.columns col2
    ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id

它会告诉你它属于哪个表。

然后你可以看看约束正在做什么......鉴于其违反FK,它可能是一个缺失的参考。

也许您有一个地址表,并列出了StateID = 123,但State表只有122行。您必须找到具有无效引用的记录并进行修复。

SELECT * 
FROM someTable T1 --the table with bad data
LEFT OUTER JOIN someOtherTable T2 ON T1.RefID = T2.ID --the lookup table
WHERE T2.ID IS NULL

如果有任何行返回,请检查其参考值。它是NULL吗?是123,但没有123吗?您将不得不找到您添加的错误数据并进行修复。

如果约束是一个唯一约束,也许你为State 123放了两行,你可以用它来查找重复项。

;WITH DUPES
AS (
SELECT *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) AS ROWID
FROM myTable
)

SELECT *
-- DELETE
FROM DUPES
WHERE ROWID>1

一旦您确认存在欺骗行为,并且您不会将所有宝贵的数据丢失,请选择删除...

找到傻瓜后,或者修复无效指针,然后尝试重新启用约束......在你这样做之前,它不会重新启用。

答案 1 :(得分:0)

约束" FK__PW_COLUMN__TABLE__3864608B"不在" PW_TABLES"它正在引用" PW_TABLES",找到与" FK__PW_COLUMN__TABLE__3864608B"相关联的表格。你需要做以下事情。

在SQL Server Management Studio中将表名粘贴到查询窗口中(即PW_TABLES) 并且按Alt + F1 ,您将获得该表的完整详细信息。

要查看所有引用约束,请拖动底部的滚动条。在底部,您将看到一个名为 &#34的列;表由外键" 引用,它将提供有关引用该表的所有约束的信息,包括表名和约束名称。

找到约束(即" FK__PW_COLUMN__TABLE__3864608B")以及与之关联的表格并将其禁用。