【问题标题】:SQL Server table creation error : There are no primary or candidate keys in the referencedSQL Server 表创建错误:引用中没有主键或候选键
【发布时间】:2016-06-17 06:15:30
【问题描述】:

一个非常基本的脚本让我发疯。它说它找不到引用的密钥。不知道这是怎么一回事。我正在使用 SQL SERVER 2014,此脚本用于创建我的数据库表。我正在尝试使表TABLE_2 中的id_TABLE_1 引用表TABLE_1 的ID。

CREATE TABLE TABLE_1
(
    id int identity,
    email varchar(50) not null,

    constraint PK_TABLE_1 primary key (id,email)
)
GO

CREATE TABLE TABLE_2
(
    id int identity,
    id_TABLE_1 int not null,
         
    constraint PK_TABLE_2 primary key (id),
    constraint FK_TABLE_2 foreign key (id_TABLE_1) 
        references TABLE_1(id) on delete cascade
)
GO

错误是:

Msg 1776,第 16 级,状态 0,第 32 行
被引用表“TABLE_1”中没有与外键“FK_TABLE_2”中的引用列列表匹配的主键或候选键。

Msg 1750,第 16 级,状态 0,第 32 行
无法创建约束或索引。查看以前的错误。

你能帮帮我吗?

【问题讨论】:

  • 错误消息准确地解释了问题所在。 OBJET_GEO.id 列上没有索引。
  • 不,您的主键是包含id,email_utilisateur 列的复合键。

标签: sql sql-server sql-server-2014


【解决方案1】:

根据评论,您正在尝试引用不存在的索引。 TABLE_1 表上的主键是包含两列的复合键:idemail

要编译,您可以将主键更改为:

CONSTRAINT PK_TABLE_1 PRIMARY KEY (id)

或仅在 id 列上创建一个新索引:

CREATE INDEX IX_TABLE_1_id ON TABLE_1 (id);

【讨论】:

  • 天哪,我什至没有看到。好的,我要做的是保留id 作为主键并使用 UNIQUE (id,email) 作为组合
  • 想一想在idemail 上添加唯一索引会达到什么效果。如果您希望每行有一个唯一的电子邮件地址,则只需在您的唯一索引中包含 email
【解决方案2】:

拥有包含标识列的复合主键没有意义。 id 列已经是唯一且非 NULL,所以它应该是主键。

如果您希望电子邮件也是唯一的,请将其从主键中删除并声明为唯一。

【讨论】:

  • 与我的问题无关。不过感谢您的建议。
  • 我经常看到由两列组成的复合集群键,第二列是一个标识。例如,(OrderKey, OrderLineKey) 将确保同一订单的所有行都在一起。而且由于它们通常会同时创建,因此索引碎片不是问题。 (也就是说,我从来没有见过身份列是第一位的。)
  • @JonathanAllen 作为一个菜鸟,我不太清楚 UNIQUE 或 PK 约束中字段顺序的区别。
  • 约束也是一个索引。所以这就是按名字、姓氏或按姓氏、名字排序的区别。
  • @JonathanAllen Cool 我不明白。 Unique 和 PK 将按照提供的字段的顺序进行检查。所以不需要先检查身份,因为它总是因行而异?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-26
相关资源
最近更新 更多