如何在 SQL 中引用复合主键
How to reference a composite primary key in SQL
我使用以下代码创建了以下 3 table。
CREATE TABLE BUILDING(
BUILDINGNO CHAR(2),
BUILDINGWING VARCHAR2(15),
BUILDINGLANE VARCHAR2(15),
CONSTRAINT BUILDING_PK PRIMARY KEY(BUILDINGNO));
CREATE TABLE ROOM(
BUILDINGNO CHAR(2),
ROOMNO CHAR(2),
ROOMCAPACITY NUMBER(3),
CONSTRAINT ROOM_PK PRIMARY KEY(BUILDINGNO,ROOMNO),
CONSTRAINT ROOM_FK1 FOREIGN KEY(BUILDINGNO) REFERENCES BUILDING(BUILDINGNO));
CREATE TABLE SPEAKER(
SPEAKERID CHAR(2),
SPEAKERNAME VARCHAR2(20),
SPEAKERADDRESS VARCHAR2(50),
SPEAKERPHONE CHAR(12),
CONSTRAINT SPEAKER_PK PRIMARY KEY(SPEAKERID));
我需要创建的第 4 个 table 是这样的。
CREATE TABLE CONFERENCESESSION(
SESSIONID CHAR(4),
BUILDINGNO CHAR(2),
ROOMNO CHAR(2),
SPEAKERID CHAR(2),
SESSIONDATE DATE,
SESSIONPRICE NUMBER(4,2),
CONSTRAINT SESSION_PK PRIMARY KEY(SESSIONID),
CONSTRAINT SESSION_FK1 FOREIGN KEY(BUILDINGNO) REFERENCES BUILDING(BUILDINGNO),
CONSTRAINT SESSION_FK2 FOREIGN KEY(ROOMNO) REFERENCES ROOM(ROOMNO),
CONSTRAINT SESSION_FK3 FOREIGN KEY(SPEAKERID) REFERENCES SPEAKER(SPEAKERID));
但是我知道 FK2 ROOMNO(倒数第二行)的约束不正确,因为 ROOM table 中的 PK 是 BUILDINGNO,ROOMNO。
此行使用的正确代码是什么?
我们声明了一个 SQL FK (FOREIGN KEY) 约束,表示列列表的子行值总是出现在其他地方,作为构成 SQL 的列列表的子行值PK(主键)或 UNIQUE NOT NULL。只要其他声明尚未暗示它,就声明它。它必须引用声明的 SQL PK(PRIMARY KEY)或 UNIQUE NOT NULL 中的列列表。因此,您必须在引用的 table 中声明它,即使 NOT NULL 和包含的较小的 PK 或 UNIQUE NOT NULL 已经暗示了这一点。
因此请注意,SQL PK 不一定是唯一但不包含较小的唯一列集的关系意义上的 PK,即不包含较小的超级键的超键,即 minimal/irreducible 超级密钥,即作为 CK(候选密钥)。
在这里,您可能需要将 buildingno
& roomno
FKs 替换为一个,(buildingno, roomno)
到 Room
:
CONSTRAINT SESSION_FK12
FOREIGN KEY(BUILDINGNO,ROOMNO) REFERENCES ROOM(BUILDINGNO,ROOMNO)
可能 适合您的 table 的含义——实际上您没有给出,所以我们无法知道,我们可以只是猜测。例如,如果 buildingno
可以 also 在 Room 中声明 PK 或 UNIQUE NOT NULL,当 roomno IS NOT NULL
实际上符合并暗示可以声明 (buildingno, roomno)
PK 或 UNIQUE NOT NULL,也许你的 FK 是 正确的 但你的 Room
声明不充分。
当列列表的子行值始终作为列列表的子行值出现在其他地方时,称为 IND(包含依赖性)约束。无法在 SQL 中申报非 FK IND;我们必须通过触发器来执行。 也可能是您设计所需要的。
您可以将 FK 从 buildingno
保留为 Building
,但我建议的 FK 和 Room
上 buildingno
中的 FK 都暗示了 Room
引用 [=20] =].
referencing part of the composite primary key
正如我们在 documentation 中看到的,我们可以创建复合外键:
CREATE TABLE CONFERENCESESSION ...
...
CONSTRAINT SESSION_FK2
FOREIGN KEY(BUILDINGNO, ROOMNO)
REFERENCES ROOM(BUILDINGNO, ROOMNO),
...
测试:
insert into building values (1, null, null);
insert into room values (1, 1, null);
insert into speaker (speakerid) values (1);
insert into conferencesession (sessionid,buildingno,roomno,speakerid) values (1, 1, 1, 1);
insert into conferencesession (sessionid,buildingno,roomno,speakerid) values (2, 1, 2, 1);
最后一次插入产生错误 ORA-02291
。
我使用以下代码创建了以下 3 table。
CREATE TABLE BUILDING(
BUILDINGNO CHAR(2),
BUILDINGWING VARCHAR2(15),
BUILDINGLANE VARCHAR2(15),
CONSTRAINT BUILDING_PK PRIMARY KEY(BUILDINGNO));
CREATE TABLE ROOM(
BUILDINGNO CHAR(2),
ROOMNO CHAR(2),
ROOMCAPACITY NUMBER(3),
CONSTRAINT ROOM_PK PRIMARY KEY(BUILDINGNO,ROOMNO),
CONSTRAINT ROOM_FK1 FOREIGN KEY(BUILDINGNO) REFERENCES BUILDING(BUILDINGNO));
CREATE TABLE SPEAKER(
SPEAKERID CHAR(2),
SPEAKERNAME VARCHAR2(20),
SPEAKERADDRESS VARCHAR2(50),
SPEAKERPHONE CHAR(12),
CONSTRAINT SPEAKER_PK PRIMARY KEY(SPEAKERID));
我需要创建的第 4 个 table 是这样的。
CREATE TABLE CONFERENCESESSION(
SESSIONID CHAR(4),
BUILDINGNO CHAR(2),
ROOMNO CHAR(2),
SPEAKERID CHAR(2),
SESSIONDATE DATE,
SESSIONPRICE NUMBER(4,2),
CONSTRAINT SESSION_PK PRIMARY KEY(SESSIONID),
CONSTRAINT SESSION_FK1 FOREIGN KEY(BUILDINGNO) REFERENCES BUILDING(BUILDINGNO),
CONSTRAINT SESSION_FK2 FOREIGN KEY(ROOMNO) REFERENCES ROOM(ROOMNO),
CONSTRAINT SESSION_FK3 FOREIGN KEY(SPEAKERID) REFERENCES SPEAKER(SPEAKERID));
但是我知道 FK2 ROOMNO(倒数第二行)的约束不正确,因为 ROOM table 中的 PK 是 BUILDINGNO,ROOMNO。 此行使用的正确代码是什么?
我们声明了一个 SQL FK (FOREIGN KEY) 约束,表示列列表的子行值总是出现在其他地方,作为构成 SQL 的列列表的子行值PK(主键)或 UNIQUE NOT NULL。只要其他声明尚未暗示它,就声明它。它必须引用声明的 SQL PK(PRIMARY KEY)或 UNIQUE NOT NULL 中的列列表。因此,您必须在引用的 table 中声明它,即使 NOT NULL 和包含的较小的 PK 或 UNIQUE NOT NULL 已经暗示了这一点。
因此请注意,SQL PK 不一定是唯一但不包含较小的唯一列集的关系意义上的 PK,即不包含较小的超级键的超键,即 minimal/irreducible 超级密钥,即作为 CK(候选密钥)。
在这里,您可能需要将 buildingno
& roomno
FKs 替换为一个,(buildingno, roomno)
到 Room
:
CONSTRAINT SESSION_FK12
FOREIGN KEY(BUILDINGNO,ROOMNO) REFERENCES ROOM(BUILDINGNO,ROOMNO)
可能 适合您的 table 的含义——实际上您没有给出,所以我们无法知道,我们可以只是猜测。例如,如果 buildingno
可以 also 在 Room 中声明 PK 或 UNIQUE NOT NULL,当 roomno IS NOT NULL
实际上符合并暗示可以声明 (buildingno, roomno)
PK 或 UNIQUE NOT NULL,也许你的 FK 是 正确的 但你的 Room
声明不充分。
当列列表的子行值始终作为列列表的子行值出现在其他地方时,称为 IND(包含依赖性)约束。无法在 SQL 中申报非 FK IND;我们必须通过触发器来执行。 也可能是您设计所需要的。
您可以将 FK 从 buildingno
保留为 Building
,但我建议的 FK 和 Room
上 buildingno
中的 FK 都暗示了 Room
引用 [=20] =].
referencing part of the composite primary key
正如我们在 documentation 中看到的,我们可以创建复合外键:
CREATE TABLE CONFERENCESESSION ...
...
CONSTRAINT SESSION_FK2
FOREIGN KEY(BUILDINGNO, ROOMNO)
REFERENCES ROOM(BUILDINGNO, ROOMNO),
...
测试:
insert into building values (1, null, null);
insert into room values (1, 1, null);
insert into speaker (speakerid) values (1);
insert into conferencesession (sessionid,buildingno,roomno,speakerid) values (1, 1, 1, 1);
insert into conferencesession (sessionid,buildingno,roomno,speakerid) values (2, 1, 2, 1);
最后一次插入产生错误 ORA-02291
。