【问题标题】:ORA-00907: "missing right parenthesis"ORA-00907:“缺少右括号”
【发布时间】:2021-04-09 19:17:08
【问题描述】:

首先,我很抱歉再次提出同样的问题,但是关于旧主题的信息在我的 oraclesql 代码中不起作用,其次可能存在一些语法错误,我上学期在学校学习了 mysql,但现在我们课上用老的mysql资料学习oraclesql,所以有点迷糊。

所以我的问题是我想创建 3 个相关表(电影演员表),但我缺少右括号。尝试使用外键将演员表连接到电影表,将演员表连接到演员表。我究竟做错了什么?意大利面怎么样?

CREATE TABLE Movie (
    movie_id NUMBER(7) NOT NULL,
    movie_name varchar2(50) NOT NULL ,
    movie_director varchar2(50) NOT NULL ,
    movie_year INT(4) NOT NULL ,
    movie_duration INT(3) ,
    movie_language varchar2(15) ,
    movie_rating number(4,2) , 
    PRIMARY KEY(movie_id),
    CONSTRAINT is_unique UNIQUE(movie_id),
    CONSTRAINT movie_id_checker CHECK(movie_id>0 and movie_id<=9999999)
);

CREATE TABLE Casts (
    movie_id_fk INT(7) FOREIGN KEY REFERENCES Movie(movie_id) ,
    
    cast_id INT(7) NOT NULL, 
    actor_fullname varchar2(50) NOT NULL ,
    actor_role varchar2(50) ,
    PRIMARY KEY(cast_id),
    CONSTRAINT is_unique UNIQUE(cast_id),
    CONSTRAINT cast_id_checker CHECK(cast_id>0 and cast_id<=9999999)
);

CREATE TABLE Actor (
    cast_id_fk INT(7) FOREIGN KEY REFERENCES Casts(cast_id) ,
    
    actor_id INT(7) NOT NULL,
    actor_name CHAR(30) ,
    actor_surname CHAR(25) ,
    actor_gender CHAR(5) ,
    actor_age CHAR(3) CONSTRAINT real_age_check CHECK(actor_age>0 AND actor_age<=150),
    PRIMARY KEY(actor_id),
    CONSTRAINT is_unique UNIQUE(actor_id),
    CONSTRAINT actor_id_checker CHECK(actor_id>0 and actor_id<=9999999)
)

【问题讨论】:

  • 创建 Casts 和创建 Actor 后为什么缺少分号?
  • 抱歉我的错:/现在添加
  • INT(4) 在 oracle 中有效吗?
  • @praveen 似乎不是 :D 感谢 mt0 先生,我知道了

标签: sql oracle create-table


【解决方案1】:

错误是:

  • INTNUMBER(4,0) 而不是 INT(4)
  • 您不能在同一列上拥有唯一键和主键。
  • 内联外键只需要REFERENCES关键字,不需要FOREIGN KEY

其他问题:

  • 您可能不希望演员姓名/姓氏作为固定长度的CHAR 字符串,而希望我们使用可变长度的VARCHAR2
  • 您可能希望性别是固定列表中的代码(可以长或短,只要您认为适合描述演员)而不是字符串。
  • 您可能不希望有AGE 列,因为一旦演员一岁生日,该列就会过时;而是有一个 DATE_OF_BIRTH 列,它是一个 DATE 数据类型,然后您可以在必要时计算年龄。
  • 使用表名作为每列的前缀是浪费击键;您最好只为不带前缀的列命名。类似fk作为后缀。
  • 如果您将NUMBER(7,0) 用于id 值,则无需检查它是否小于或等于9999999,因为不可能是更大的值;但是,您可以使用零值或负值,因此下限的检查约束可能仍然有效。
  • 如果您使用的是 Oracle 12c 或更高版本,那么您可能应该为 id 值使用 IDENTITY 列,除非您从第 3 方获取 id 值。
CREATE TABLE Movie (
    id       NUMBER(7,0) NOT NULL,
    name     varchar2(50) NOT NULL ,
    director varchar2(50) NOT NULL ,
    year     NUMBER(4,0) NOT NULL ,
    duration NUMBER(3,0),
    language varchar2(15) ,
    rating   number(4,2) , 
    PRIMARY KEY(id),
    CONSTRAINT movie_id_checker CHECK(id>0)
);

CREATE TABLE Casts (
    movie_id INT REFERENCES Movie(id) ,
    id       NUMBER(7,0) NOT NULL, 
    fullname varchar2(50) NOT NULL ,
    role     varchar2(50) ,
    PRIMARY KEY(id),
    CONSTRAINT cast_id_checker CHECK(id>0)
);

CREATE TABLE Actor (
    cast_id       NUMBER(7,0) REFERENCES Casts(id) ,
    id            NUMBER(7,0) NOT NULL,
    name          VARCHAR2(30) ,
    surname       VARCHAR2(25) ,
    gender        CHAR(1)
                  CHECK ( gender IN ( 'M', 'F', 'X', 'Y', 'Z' ) ),
    date_of_birth DATE
                  CONSTRAINT real_age_check CHECK(date_of_birth >= DATE '1870-01-01' ),
    PRIMARY KEY(id),
    CONSTRAINT actor_id_checker CHECK(id>0)
);

db小提琴here

【讨论】:

  • 1-)cast_id NUMBER(7,0) NOT NULL, 2-) 类似于 mysql 主键 = 唯一键 + 非 Null 3-) cast_id_fk NUMBER(7,0) 参考 Casts(cast_id) ,像那样?
  • 注意:非常感谢你的队友,它终于可以工作了,看起来像在 mysql 中是的 Primary Key = Unique Key + Not Null
  • 我使用表名作为前缀以便于理解,但我不会再这样做了,新手错误:/
  • @blawien 您可以在列名前加上表名,但这是不必要的,只会增加您必须输入的数量;但是,如果它可以帮助您使代码正确并减少错误,那么额外的输入对您很有价值。因此,为表名添加前缀并没有错,您可以忽略该建议....但这并不符合每个人的口味(这就是我添加该评论的原因)。
猜你喜欢
  • 2018-05-23
  • 2018-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多