【问题标题】:Can't find the solution to an error ORA-02270找不到错误 ORA-02270 的解决方案
【发布时间】:2021-09-15 16:33:13
【问题描述】:

我想将 ERD 模式转换为关系模式。我写了一些命令,但其中一些不起作用。

当我尝试执行这个命令时:

CREATE TABLE Egzemplarz_papierowy(
id_egzemplarza INTEGER NOT NULL, 
id_autora INTEGER REFERENCES Autor(id_autora), 
tytuł CHAR(20) NOT NULL REFERENCES Książka(tytuł), 
PRIMARY KEY(id_egzemplarza, id_autora, tytuł), 
nazwa_działu CHAR(20) REFERENCES Dział(nazwa_działu), 
rok_wydania INTEGER NOT NULL,
status_wypożyczenia CHAR(20) NOT NULL,
okładka CHAR(20) NULL, 
liczba_stron INTEGER NOT NULL);

发生错误:ORA-02270。我知道它告诉我主键不匹配,但我不明白为什么,因为实体 Książka 的主键是匹配的,我只在此处添加 id_egzemplarza。我该怎么办?

完整代码:

CREATE TABLE Autor(id_autora INTEGER PRIMARY KEY, imię CHAR(20) NOT NULL, nazwisko CHAR(20) NOT NULL);

CREATE TABLE Dział(nazwa_działu CHAR(20) PRIMARY KEY, liczba_egzemplarzy INTEGER NOT NULL, liczba_egzemplarzy_wypożyczonych INTEGER NOT NULL);

CREATE TABLE Książka(tytuł CHAR(20) NOT NULL, id_autora INTEGER REFERENCES Autor(id_autora), nazwa_działu CHAR(20) REFERENCES Dział(nazwa_działu), PRIMARY KEY(tytuł, id_autora), liczba_egzemplarzy INTEGER NOT NULL, liczba_egzemplarzy_wypożyczonych INTEGER NOT NULL);

CREATE TABLE Egzemplarz_papierowy(id_egzemplarza INTEGER NOT NULL, id_autora INTEGER REFERENCES Autor(id_autora), tytuł CHAR(20) NOT NULL REFERENCES Książka(tytuł), PRIMARY KEY(id_egzemplarza, id_autora, tytuł), nazwa_działu CHAR(20) REFERENCES Dział(nazwa_działu), rok_wydania INTEGER NOT NULL, status_wypożyczenia CHAR(20) NOT NULL, okładka CHAR(20) NULL, liczba_stron INTEGER NOT NULL);

CREATE TABLE Egzemplarz_elektroniczny(id_egzemplarza INTEGER NOT NULL, id_autora INTEGER REFERENCES Autor(id_autora), tytuł CHAR(20) NOT NULL REFERENCES Książka(tytuł), PRIMARY KEY(id_egzemplarza, id_autora, tytuł), rok_wydania INTEGER NOT NULL, status_wypożyczenia CHAR(20) NOT NULL, okładka CHAR(20) NULL, format_pliku CHAR(20) NOT NULL);

CREATE TABLE Karta_użytkownika(PESEL VARCHAR(11) PRIMARY KEY, imię CHAR(20) NOT NULL, nazwisko CHAR(20) NOT NULL, balans_konta INTEGER NOT NULL);

CREATE TABLE Należy(id_autora INTEGER REFERENCES Autor(id_autora), nazwa_działu CHAR(20) REFERENCES Dział(nazwa_działu), PRIMARY KEY(id_autora, nazwa_działu));

CREATE TABLE Wypożyczenie_papierowy(data_wypożyczenia DATE NOT NULL, id_autora REFERENCES Autor(id_autora), tytuł REFERENCES Książka(tytuł), id_egzemplarza REFERENCES Egzemplarz_papierowy(id_egzemplarza), pesel REFERENCES Karta_użytkownika(PESEL), PRIMARY KEY(data_wypożyczenia, id_autora, tytuł, pesel), rzeczywista_data_zwrotu DATE, deadline_daty_zwrotu DATE, status_wypożyczenia CHAR(20));

CREATE TABLE Wypożyczenie_elektroniczny(data_wypożyczenia DATE NOT NULL, id_autora REFERENCES Autor(id_autora), tytuł REFERENCES Książka(tytuł), id_egzemplarza REFERENCES Egzemplarz_elektroniczny(id_egzemplarza), pesel REFERENCES Karta_użytkownika(PESEL), PRIMARY KEY(data_wypożyczenia, id_autora, tytuł, pesel), rzeczywista_data_zwrotu DATE, deadline_daty_zwrotu DATE, status_wypożyczenia CHAR(20));

【问题讨论】:

    标签: sql oracle schema erd relational


    【解决方案1】:

    不能将多列约束定义为一列的一部分 - 它必须是单独的定义。所以这个:

    tytuł CHAR(20) NOT NULL REFERENCES Książka(tytuł)
    

    行不通,因为Książka的PK是

    CREATE TABLE Książka( ... PRIMARY KEY(tytuł, id_autora) );
    

    引用它的 FK 需要命名两列,如下所示:

    foreign key (tytuł, id_autora) references książka(tytuł, id_autora)
    

    固定脚本(前四个表):

    create table autor
    ( id_autora                         integer primary key
    , imię                              varchar2(20) not null
    , nazwisko                          varchar2(20) not null );
    
    create table dział
    ( nazwa_działu                      varchar2(20) primary key
    , liczba_egzemplarzy                integer not null
    , liczba_egzemplarzy_wypożyczonych  integer not null);
    
    create table książka
    ( tytuł                             varchar2(20) not null
    , id_autora                         references autor(id_autora)
    , nazwa_działu                      references dział(nazwa_działu)
    , liczba_egzemplarzy                integer not null
    , liczba_egzemplarzy_wypożyczonych  integer not null
    , primary key(tytuł, id_autora)
    );
    
    create table egzemplarz_papierowy
    ( id_egzemplarza                    integer not null
    , id_autora                         references autor(id_autora)
    , tytuł                             varchar2(20) not null
    , nazwa_działu                      references dział(nazwa_działu)
    , rok_wydania                       integer not null
    , status_wypożyczenia               varchar2(20) not null
    , okładka                           varchar2(20) null
    , liczba_stron                      integer not null
    , primary key(id_egzemplarza, id_autora, tytuł)
    , foreign key (tytuł, id_autora) references książka(tytuł, id_autora)
    );
    

    您可能会考虑命名约束,因为这样任何违规错误都将更容易追踪,尽管我有时希望他们能找到一种不需要命名约束的方式来表达错误消息,例如not null.

    你应该avoid CHAR,因为它是一个没有任何优势的错误陷阱,旨在(我只能想象)ANSI 完整性和跨平台可移植性,而不是任何有用的功能,因为它没有。

    对于单列外键约束,可以省略数据类型,让它从父表继承,我认为这是更好的做法。

    【讨论】:

      【解决方案2】:

      Egzemplarz_papierowyEgzemplarz_elektronicznyWypożyczenie_papierowyWypożyczenie_elektroniczny 表的键定义存在问题。在这些表中的每一个中,都尝试在单个字段上创建外键约束 - 但是,目标表上的主键是多列键。比如你对Egzemplarz_papierowy的定义是:

      CREATE TABLE Egzemplarz_papierowy(
      id_egzemplarza INTEGER NOT NULL, 
      id_autora INTEGER REFERENCES Autor(id_autora), 
      tytuł CHAR(20) NOT NULL REFERENCES Książka(tytuł), 
      PRIMARY KEY(id_egzemplarza, id_autora, tytuł), 
      nazwa_działu CHAR(20) REFERENCES Dział(nazwa_działu), 
      rok_wydania INTEGER NOT NULL,
      status_wypożyczenia CHAR(20) NOT NULL,
      okładka CHAR(20) NULL, 
      liczba_stron INTEGER NOT NULL);
      

      由于tytuł 字段上的 REFERENCES 子句,此操作失败:

      tytuł CHAR(20) NOT NULL REFERENCES Książka(tytuł),
      

      因为字段tytuł 既不是表Książka 上的主键也不是唯一键。外键必须引用目标表上的所有字段,这些字段处于主键或唯一键约束中。

      要更正此问题,您应该更改外键约束以包含 Książka 表的主键中的所有列:

      CREATE TABLE Egzemplarz_papierowy
       (id_egzemplarza INTEGER
         NOT NULL,
        id_autora INTEGER
          REFERENCES Autor(id_autora),
        tytuł CHAR(20)
          NOT NULL,
        FOREIGN KEY (tytuł, id_autora)
          REFERENCES Książka(tytuł, id_autora),
        PRIMARY KEY(id_egzemplarza, id_autora, tytuł),
        nazwa_działu CHAR(20)
          REFERENCES Dział(nazwa_działu),
        rok_wydania INTEGER
          NOT NULL,
        status_wypożyczenia CHAR(20)
          NOT NULL,
        okładka CHAR(20)
          NULL,
        liczba_stron INTEGER NOT NULL);
      

      这编译正确。 Egzemplarz_elektronicznyWypożyczenie_papierowyWypożyczenie_elektroniczny 表有类似的问题。

      db<>fiddle here

      【讨论】:

        【解决方案3】:

        问题似乎与表 Książka 的定义有关,它具有包含列 tytuł、id_autora 的复合主键,但是当您创建外键时,您只引用了列 tytuł

        你应该改变你的创建表如下:

        CREATE TABLE Egzemplarz_papierowy(
        id_egzemplarza INTEGER NOT NULL, 
        id_autora INTEGER REFERENCES Autor(id_autora), 
        tytuł CHAR(20) NOT NULL REFERENCES Książka(tytuł, id_autora), 
        PRIMARY KEY(id_egzemplarza, id_autora, tytuł), 
        nazwa_działu CHAR(20) REFERENCES Dział(nazwa_działu), 
        rok_wydania INTEGER NOT NULL,
        status_wypożyczenia CHAR(20) NOT NULL,
        okładka CHAR(20) NULL, 
        liczba_stron INTEGER NOT NULL);
        

        【讨论】:

          【解决方案4】:

          在Oracle中定义PK的语法是:

          CONSTRAINT constraint_name PRIMARY KEY (column1, column2, ... column_n)
          

          【讨论】:

          • 这是一个有效的语法。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-08
          • 1970-01-01
          • 2019-05-24
          • 2016-07-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多