此处的最终目标是重新启用数据库中的所有约束。
这里有关于发生的事情的一些背景知识。我是一个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'。
我尝试在其他表中运行相同的东西,但约束不在哪里可以找到。如何再次启用数据库中的所有约束?
答案 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")以及与之关联的表格并将其禁用。