【问题标题】:There are no primary or candidate keys in the referenced table error引用的表错误中没有主键或候选键
【发布时间】:2016-06-08 01:37:58
【问题描述】:

我在将外键组合到不同表时遇到问题。例如我制作了一张表客户和一张表发票。我想要一个从客户到发票的外键,这样我就可以获得客户的姓名和所有信息:

创建Customers的表代码:

Create Table Customers
(
    customerID int IDENTITY(100,1) NOT NULL, 
    customer_email varchar(30) NOT NULL,
    username varchar(255) NOT NULL,
    password varchar(50) NOT NULL,
    firstname varchar(255) NOT NULL,
    lastname varchar(255) NOT NULL,
    insertion varchar(10)   NULL,
    phonenumber int NULL,
    streetname varchar(20) NOT NULL,
    number  int NOT NULL,
    zipcode varchar(10) NOT NULL,
    city    varchar(255) NOT NULL,

    Constraint pk_Customers 
       PRIMARY KEY (customerID, customer_email, username)
)

创建Invoices的表代码:

Create Table Invoices 
(
    invoiceID int IDENTITY(1000,1) NOT NULL,
    customer_email varchar(30) NOT NULL,
    customerID int NOT NULL,
    creationdate datetime NOT NULL DEFAULT GETDATE(),
    totalAmount decimal(5,2) NOT NULL,

    Constraint pk_Invoices 
        PRIMARY KEY (invoiceID, customer_email,creationdate)
) 

我要使用的外键码:

ALTER Table Invoices
ADD Constraint fk_Customers_Invoices 
FOREIGN KEY (customerID) REFERENCES Customers (customerID)
   ON UPDATE CASCADE 
   ON DELETE NO ACTION

它会抛出以下错误:

引用表“客户”中没有与外键“fk_Customers_Invoices”中的引用列列表匹配的主键或候选键。

如何添加我的外键?

【问题讨论】:

  • 有点奇怪的结构。如果CustomerIDidentity 列,那么为什么PRIMARY KEY 中还有其他列?您的两个 PK 都必须通过身份 col。我什至无法想象对 customer_email+creationdate 进行唯一约束的目的是什么...您收到错误消息,因为您的 PK 包含三列,但您尝试仅使用一列来引用它柱子。一列不足以定位由三列标识的记录。如上所述修复你的 PK,FK 就可以正常工作。

标签: sql sql-server foreign-keys


【解决方案1】:

由于您的 Customers 表定义了这个主键:

Constraint pk_Customers 
   PRIMARY KEY (customerID, customer_email, username)

任何想要引用Customers 的表必须提供该主键的所有三列。这就是 FK 约束的工作方式。

因此,从您的 Invoices 表中,您必须提供构成 Customers 主键的所有 3 列 - 而不仅仅是一个。您可以从不仅引用主键的一部分 - 它是整个键或什么都没有......

ALTER Table Invoices
ADD Constraint fk_Customers_Invoices 
FOREIGN KEY (customerID) REFERENCES Customers (customerID)
   ON UPDATE CASCADE 
   ON DELETE NO ACTION

您可以任一

  • Customers 的 PK 更改为 CustomerID,这样会更有意义,因为它是 身份

  • 或者您可以将 Customers PK 中的其他两列添加到 yoru 表 Invoices

【讨论】:

  • 但是这样我仍然可以使用 UNIQUE 函数对吗?
  • @CarstenFlokstra:不知道你指的是什么 - UNIQUE on / for what ?!?!?
  • 数据库中存在唯一值 customer_email 和 username。
  • 在 customer_email 地址中有用户名副本很奇怪。
  • @CarstenFlokstra:在这种情况下,让CustomerID 单独成为PK!这是最有意义的。然后您在其他表中也没有“用户名”和“customer_email”地址的“副本”......为了确保(username, customer_email) 的唯一性,您始终可以放置一个 UNIQUE CONSTRAINT在这两列上 - 他们不需要成为 PK 的一部分!
【解决方案2】:

我认为这是因为您的主键是复合键:

customerID, customer_email, username

这表明只有这三个字段的组合才能唯一标识客户,并且外键需要引用所有三个字段。

如果 customerID 是唯一的,那么它应该是表的主键,您的外键可以将其用作参考。

其他字段包含在主键中的目的是什么?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 2018-12-25
    • 2022-01-07
    • 1970-01-01
    相关资源
    最近更新 更多