数据库创建表未找到主键

时间:2017-04-07 01:23:22

标签: sql oracle

我有两个表,我正在尝试使用外键创建。 声明如下:

Book_Copy表

CREATE TABLE book_copy (
    bid          NUMBER(15) NOT NULL,
    isbn         VARCHAR(15) NOT NULL,
    firstavaib   VARCHAR(9) NOT NULL,
    outservice   VARCHAR(9) NULL,
    CONSTRAINT primary_key PRIMARY KEY ( bid,isbn ),
    FOREIGN KEY ( isbn )
        REFERENCES book_catalog ( isbn )
);

历史表

CREATE TABLE history (
    bid          NUMBER(15) NOT NULL,
    mid          NUMBER(10) NOT NULL,
    FOREIGN KEY ( mid )
        REFERENCES member ( mid ),
    datetaken    VARCHAR(9) NOT NULL,
    datereturn   VARCHAR(9) NULL,
    FOREIGN KEY ( bid )
        REFERENCES book_copy ( bid ),
    CONSTRAINT primary_key PRIMARY KEY ( bid, datetaken )
);

现在,当我运行它时,第一个表示创建了表,但我得到了第二个表。

CREATE TABLE history (
    bid          NUMBER(15) NOT NULL,
    mid          NUMBER(10) NOT NULL,
    FOREIGN KEY ( mid )
        REFERENCES member ( mid ),
    datetaken    VARCHAR(9) NOT NULL,
    datereturn   VARCHAR(9) NULL,
    FOREIGN KEY ( bid )
        REFERENCES book_copy ( bid ),
   CONSTRAINT primary_key PRIMARY KEY ( datetaken )

)                                                                                                                                                                                                                  * 第1行的错误:

  

ORA-02270:此列列表没有匹配的唯一键或主键

2 个答案:

答案 0 :(得分:0)

错误:外键(BID)引用Book_Copy(BID)

Book_Copy的主键是(BID,DateTaken)而不仅仅是(BID)

在另一个表的FK中引用的目标表中需要主要或唯一约束。

1)在HISTORY上将DateTaken添加到FK定义或用CHECK约束替换FK(EXISTS(从book_copy c中选择*,其中c.BID = BID)

答案 1 :(得分:0)

上述陈述中有几处错误,并非所有相关信息都可用。

您的表格book_copy通过book_catalog列提供了对表格isbn的外键引用:

CREATE TABLE book_copy (
    ...
    FOREIGN KEY ( isbn )
        REFERENCES book_catalog ( isbn )

为了继续,我冒昧地添加一个简单的:

CREATE TABLE book_catalog (
    isbn VARCHAR(15) NOT NULL,
    CONSTRAINT pk_ct PRIMARY KEY (isbn));

类似地,他们history表还通过member列引用了另一个表mid

CREATE TABLE history (
    ...
    FOREIGN KEY ( mid )
        REFERENCES member ( mid ),

我还创建了一个以便继续:

CREATE TABLE MEMBER (
    mid NUMBER(10) NOT NULL,
    CONSTRAINT pk_mem PRIMARY KEY (mid));

您获得的错误意味着它所说的内容:您尝试引用的另一个表上没有此类主键或唯一键,因此无法唯一标识值,因此未验证数据的完整性。因此,数据库首先阻止您这样做。

罪魁祸首是您将表PRIMARY KEY的{​​{1}}指定为book_copy,而bid,isbn表中的外键引用仅引用history }:

bid

因此,您要求数据库检查不可识别的内容的完整性。为了解决这个问题,您必须扩展历史记录表的外键以包含CREATE TABLE history ( ... FOREIGN KEY ( bid ) REFERENCES book_copy ( bid ), 列:

所以完整的DDL看起来像这样:

isbn

上面的DDL还有另一个问题。在Oracle中,约束名称是全局唯一的!这意味着在CREATE TABLE book_catalog ( isbn VARCHAR(15) NOT NULL, CONSTRAINT book_catalog_pk PRIMARY KEY (isbn)); CREATE TABLE MEMBER ( mid NUMBER(10) NOT NULL, CONSTRAINT member_pk PRIMARY KEY (mid)); CREATE TABLE book_copy ( bid NUMBER(15) NOT NULL, isbn VARCHAR(15) NOT NULL, firstavaib VARCHAR(9) NOT NULL, outservice VARCHAR(9) NULL, CONSTRAINT book_copy_pk PRIMARY KEY ( bid,isbn ), FOREIGN KEY ( isbn ) REFERENCES book_catalog ( isbn ) ); CREATE TABLE history ( bid NUMBER(15) NOT NULL, mid NUMBER(10) NOT NULL, isbn VARCHAR2(15) NOT NULL, FOREIGN KEY ( mid ) REFERENCES member ( mid ), datetaken VARCHAR(9) NOT NULL, datereturn VARCHAR(9) NULL, FOREIGN KEY ( bid, isbn ) REFERENCES book_copy ( bid, isbn ), CONSTRAINT history_pk PRIMARY KEY ( bid, datetaken ) ); 之后放置的任何内容都必须是唯一的。在上面的情况中,对于两个表使用相同的名称CONSTRAINT,这些表将在创建历史记录表时出现primary_key错误。您将看到我已经在表上给出了更有意义的名称的主键约束。