SQL Server 2008:表中的列与现有的主键或唯一约束条件不匹配

67

我需要对一个 SQL Server 2008 数据库进行一些更改。

这需要创建一个新表,并在新表中插入一个外键,引用已经存在的表的主键。所以我想在我的新 tblTwo 和 tblOne 的主键之间建立关系。

然而,当我尝试通过 SQL Server 管理工具来实现时,出现了以下错误:

表 'tblOne' 中的列没有匹配到现有的主键或唯一性约束

我不太确定这是什么意思,想知道是否有任何解决方法?

13个回答

94

这意味着tblOne中的主键未被正确声明 - 您需要转到tblOne并将PRIMARY KEY约束添加回去。

如果您确定tblOne确实有PRIMARY KEY约束,则可能在您的数据库中有多个属于不同模式的tblOne表,而您的FK约束中的引用子句正在选择错误的表。

如果有复合键(您的评论会指示出这一点),则您还必须在外键引用中包括两个列。请注意,表不能具有多个主键 - 但是,如果它具有复合键,则您将在每个列旁边看到一个键符号,该列是主键的一部分。


嗨,达米安,数据库中只有一个tblOne,并且它肯定有一个PK。我注意到一件事情(我没有参与数据库的创建,很少接近它),就是tblOne中有两个主键(所以是复合键?)。这会影响它吗? - 109221793
更新了我的回答 - 你必须在外键约束中包含两个列。 - Damien_The_Unbeliever
如果您有一个复合键,确保已添加所有列,但仍然出现此问题,请参见下面alanh的答案。 - Turch
如果有复合键,我应该在另一个表中添加两列(2个外键)并将它们引用到复合主键中的列,还是只创建一列(1个外键)并将其引用到复合键中? - Hanady
9
按照“alanh”的说法,对于复合键,键的顺序很重要。 - Dhanuka777

65
如果您有一个复合键,在创建FK时顺序很重要,而且有时顺序不是按照显示的方式。我的做法是进入table1的Keys部分,并选择脚本主键为创建到剪贴板,然后按照脚本中显示的顺序创建FK。

3
这是一个重要的答案。谢谢,它确实很有帮助。 - BigMan
1
感谢上帝,我往下滚动找到了这个答案! - Hasan Baidoun
你让我的一天变得美好...谢谢 - Kadeer Mughal

5

我曾经遇到过一种情况,导致我涉足了这个话题。虽然错误相同,但原因不同。也许会对某些人有所帮助。

Table1
ColA (PK)
ColB (PK)
ColC


Table2
ID (PK)
ColA
COLB

尝试在 Table2 中创建外键时,我选择了反向从下拉列表中选择的值。
Table1.ColB = Table2.ColB
Table1.ColA = Table2.ColA

这个问题的错误提示与主题名称相同。将外键创建时保持列的顺序与主键表中的顺序一致,可以使错误消失。

有些愚蠢,但是有效 :)


5
如果您已经按照上面的建议进行了操作,一切看起来都正确,但仍然出现错误,请不要担心。解决这个问题的一个方法是删除两个表的主键,保存并刷新,然后再添加它们。接着尝试重新建立关系即可。

我在更改关系所引用的表时遇到了问题。但是我没有成功地更改它,而是删除了它并创建了一个新的关系。你说得对,这最终起作用了。 - Mark

4

当我尝试从主键表开始添加外键约束时,出现了这个错误。

只需前往其他表并从那里创建此外键约束(外键表)。


2

这个问题让我困扰了一段时间,原来是我在错误的表格上添加了关系。所以如果你想在表格A中添加到表格B的关系,请尝试在表格B中添加从表格A到表格B的关系。


0
在我的情况下,错误发生是因为我使用了SSMS设计面板来添加关系(该关系指向一个复合唯一约束)。
通过手动编写ALTER TABLE查询,并遵守复合唯一约束的键的顺序,我能够定义外键约束。

0
我发现列名必须匹配。
例如: 如果tblOne有一个名为categoryId的id,在tblTwo中的引用也必须称为categoryId。
_tblname, primary key name, foreign key_
tblOne, "categoryId", none
tblTwo, "exampleId", "categoryId"

我注意到当我尝试在两个表之间创建外键时,它们都将" id "列作为主键。


1
这并不适用于SQL Server 2008 R2。 - Mario
1
是的,只要定义了关系,列名不必匹配。 - Mario

0

如果您的表中有数据,这可能是问题所在。

在我的情况下,我在下午3点加载了一些帐户表中的数据,以及在下午3:10分加载了一些联系人表中的数据,因此联系人表中有一些尚未出现在我的帐户表中的值。

最终,我删除了联系人表中的这些值,然后成功添加了一个键而没有遇到任何问题。


0

看起来你正在尝试在tblTwo中创建一个外键,但它与tblOne中的任何主键或唯一索引不匹配(或没有参与匹配)。

请查看MSDN上的此链接。这里是另一个具有实际案例的链接。

编辑:

回答您的评论,我理解您的意思是主键中有2个字段(使其成为复合键)。在SQL中,不可能在同一表中拥有两个主键。

在我看来,外键字段应始终引用所引用表中的单个记录(即在您的情况下是整个主键)。这意味着在创建外键之前,您需要将tblOne主键的两个字段放入tblTwo中。

无论如何,我在互联网上进行了一些调查,似乎SQL Server 2008(以及某些之前版本和其他RDBMS)可以提供仅引用主键的部分的可能性,只要此部分是候选键(非空和唯一),并且您在其上创建唯一约束。

我不确定您是否可以在您的情况下使用它,但请查看此link以获取更多信息。


2
一个外键可以引用另一张表上的任何唯一键约束 - 它不必是复合主键的一部分才能被引用 - 这个特性至少从 SQL Server 2000 开始就已经存在了。 - Damien_The_Unbeliever
1
严谨地说,如果一个单独的列有唯一约束,则包括该列的多列约束不是主键,因为它不是最小超键。 这是SQL的(许多)非关系型怪异之一,它有一个名为“PRIMARY KEY”的约束,用于不是主键的事物! - nvogel
@Guillem Vicens:我认为你应该删除那句话,开头是“无论如何,我在互联网上进行了一些调查...”它不是事实正确的(例如,NOT NULL不是必需的,不需要成为PK的一部分等),这是标准SQL的一个特性,不仅限于SQL Server 2008版本,正如评论中所确认的(包括你自己的评论! :) - onedaywhen
@Damien_The_Unbeliever,我猜你的意思是它应该读作“仅引用主键或唯一键的部分”? - Guillem Vicens
@Guillem - 不行。基本上,FOREIGN KEY 必须引用完整的键。这可以是 PRIMARY KEY 或 UNIQUE (KEY)。就是这样。没有能力引用 PK 的一部分。链接到答案中有效的 FK 之所以有效,是因为它引用了一个 UNIQUE KEY。就是这样。这个唯一键碰巧是 PK 的一部分是完全无关紧要的。 - Damien_The_Unbeliever
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接