引用多个值的主键的外键

时间:2019-03-07 06:31:12

标签: sql sql-server foreign-keys

我正在使用ms sql服务器。当我引用一个主键,该主键是外键中3个值的复合键时,就会收到此消息。

“外键中的引用列数与引用列数不同”。问题出在会员预订的第二行代码。有任何想法吗?预先感谢。

CREATE TABLE room
(
Block CHAR (1),
Lvl INT,
rNum INT,
RmType VARCHAR (15),
Condition VARCHAR (15),
CONSTRAINT room_PK PRIMARY KEY (Block, Lvl, rNum),
)




CREATE TABLE booking
(
BookingID INT,
BStartDate DATE,
BEndDate DATE,
Fee DECIMAL (8,2) NOT NULL CHECK (fee >= 0),
Memberbooking INT NOT NULL,
MemberID INT NOT NULL,
CONSTRAINT booking_pk PRIMARY KEY (BookingID),
CONSTRAINT FK_Booking FOREIGN KEY (Memberbooking) references room (Block, Lvl, rNum),
CONSTRAINT FK_MemberID FOREIGN KEY (MemberID) references member (ID)
)

4 个答案:

答案 0 :(得分:0)

您在表booking中定义此约束:

CONSTRAINT FK_Booking FOREIGN KEY (Memberbooking) references room (Block, Lvl, rNum)

表示您希望列Memberbooking引用表room中的3列(!!)。
一个表中的每一列都可以引用另一张表中的一列,而不是多个。
您可以定义同一列以引用另一个表中的多个列,但具有不同的约束,并且始终为1到1。
在此处阅读更多信息:Create Foreign Key Relationships

答案 1 :(得分:0)

由于尝试将1列(FOREIGN KEY(会员预订))与3列空间(Block,Lvl,rNum)映射而出现错误

  

可以为化合物创建外键关系(更多   (而不是一列)主键,请确保在您的外键中指定相同的列数

答案 2 :(得分:0)

由于我从评论中看到您打算实施这种检查,所以我提出了检查约束:

self

但是,这种设计不是很好。 Membermooking字段中缺少分隔符可能会导致冲突。

例如,考虑您拥有一个会员簿:“ A1101”

那是A座11级,编号01吗?还是A级,第1级,rNum 101?

答案 3 :(得分:0)

在“房间”表上,您当前具有复合自然键。这是一个有效的设计决策。替代方法是添加单列人工ID,例如int Identity。这将导致在同一张表上出现两个键(一个是主键,另一个是唯一约束)。

在外键约束中,您可以引用任何唯一约束或主键。如果要保持“房间”表的原样,则需要在引用表中镜像那些关键字段。因此,这意味着您的“预订”表将需要一个Block char(1),Lvl int和rNum int列。

这就是为什么在房间使用人工钥匙的原因,因为您的外键约束(在预订时)可以是单列,并且引用唯一约束。