21

过去两天我一直在查看这段代码,但我似乎无法让它工作。它不断地给我

ORA-00907: missing right parenthesis.

我知道这是一个经常出现的话题,但由于某种原因,我所看到的例子都没有帮助我。有人可以告诉我为什么会出现此错误以及如何解决吗?我很确定这与我的括号无关,也许是我的约束?

DROP TABLE T_customers CASCADE CONSTRAINTS;
DROP TABLE dvd_collection CASCADE CONSTRAINTS;
DROP TABLE vhs_collection CASCADE CONSTRAINTS;

CREATE TABLE T_customers   (


                           customer_id         VARCHAR2 (8) PRIMARY KEY,
                           last_name           VARCHAR2 (30) NOT NULL,
                           first_name          VARCHAR2 (20) NOT NULL,
                           street             VARCHAR2 (30) NOT NULL,
                           city               VARCHAR2 (30) NOT NULL,
                           state                 CHAR (2) NOT NULL,
                                    CHECK (state IN ('GA','DC','VA','NY')),
                           zip_code           CHAR (5)
                                    CHECK (TO_NUMBER(zip_code)
                              BETWEEN 10000 AND 27999),
                           home_phone         VARCHAR2 (12) UNIQUE,
                           work_phone         VARCHAR2 (12) UNIQUE,
                           email                 VARCHAR2 (95) NOT NULL);




CREATE TABLE historys_T    (

          history_record       VARCHAR2 (8),
          customer_id       VARCHAR2 (8), 
          CONSTRAINT historys_T_FK FOREIGN KEY (customer_id) REFERENCES T_customer
                                       ON DELETE CASCADE,
                           order_id           VARCHAR2 (10) NOT NULL,
                                 CONSTRAINT fk_order_id_orders  
                                       REFERENCES orders
                                       ON DELETE CASCADE);


CREATE TABLE orders     (

                           order_id           VARCHAR2 (10) PRIMARY KEY,
                           m_p_unique_id       VARCHAR2 (10),
                                    CONSTRAINT orders_FK FOREIGN KEY (m_p_unique_id) REFERENCES library (m_p_unique_id)
                           order_date          DATE DEFAULT);



CREATE TABLE library_T     (

                           m_p_unique_id       VARCHAR2 (10)  PRIMARY KEY,
                           movie_title         VARCHAR2 (80)  NOT NULL,
                           serial_number       VARCHAR2 (10)  NOT NULL,
                           movie_id_number   VARCHAR2 (10)  NOT NULL,
                           movie_cast        VARCHAR2 (100) NOT NULL,
                           movie_format    CHAR (3) NOT NULL, 
                                  CONSTRAINT library_FK REFERENCES formats (movie_format));

CREATE TABLE formats_T     (

                           movie_format      CHAR (3) PRIMARY KEY,
                           movie_title       VARCHAR2 (80) NOT NULL,
                           m_p_unique_id     VARCHAR2 (10) NOT NULL,
                                 CONSTRAINT format_FK  REFERENCES library (m_p_unique_id));



CREATE TABLE dvd_collection (      


                           m_p_unique_id       VARCHAR2 (10) NOT NULL,
                           serial_number       VARCHAR2 (10) NOT NULL,
                           movie_id_number  VARCHAR2 (10) NOT NULL,
                           movie_title         VARCHAR2 (80) NOT NULL,
                           movie_cast          VARCHAR2 (100) NOT NULL,
                           movie_format     VARCHAR2 (80) NOT NULL,
                           movie_rating    VARCHAR2 (6) NOT NULL,
                           movie_distributer    VARCHAR2 (30) NOT NULL,
                           movie_price         NUMBER (3,2) NOT NULL,
                           movie_length     NUMBER (3) NOT NULL,
                           movie_award         VARCHAR2 (175) NOT NULL,
                           movie_release       DATE); 


CREATE TABLE vhs_collection            
(

                           m_p_unique_id       VARCHAR2 (10)NOT NULL,
                           serial_number       VARCHAR2 (10) NOT NULL,
                           movie_id_number  VARCHAR2 (10) NOT NULL,
                           movie_title         VARCHAR2 (80) NOT NULL,
                           movie_cast        VARCHAR2 (100) NOT NULL,
                           movie_format    VARCHAR2 (80) NOT NULL,
                           movie_rating    VARCHAR2 (6) NOT NULL,
                           movie_distributer    VARCHAR2 (30) NOT NULL,
                           movie_price         NUMBER (3,2) NOT NULL,
                           movie_length     NUMBER (3) NOT NULL,
                           movie_award         VARCHAR2 (175) NOT NULL,
                           movie_release        DATE);

以下是我运行代码时得到的结果:

Table dropped.

Table dropped.

Table dropped.

Table created.

                                       ON DELETE CASCADE)
                                       *

ERROR at line 10:
ORA-00907: missing right parenthesis

                           order_date          DATE DEFAULT)
                           *

ERROR at line 6:
ORA-00907: missing right parenthesis

                                  CONSTRAINT library_FK REFERENCES formats (movie_format))
                                                                           *

ERROR at line 9:
ORA-00907: missing right parenthesis

                                 CONSTRAINT format_FK  REFERENCES library (m_p_unique_id))
                                                                          *

ERROR at line 6:
ORA-00907: missing right parenthesis
Table created.

Table created.               
4

4 回答 4

31

ORA-00907: 缺少右括号

这是几个通用错误消息之一,表明我们的代码包含一个或多个语法错误。有时这可能意味着我们从字面上省略了右括号;这很容易验证我们是否使用了具有匹配括号功能的编辑器(大多数针对编码人员的文本编辑器都这样做)。但通常这意味着编译器遇到了脱离上下文的关键字。或者它可能是一个拼写错误的单词、一个空格而不是下划线或缺少逗号。

不幸的是,我们的代码无法编译的可能原因实际上是无限的,而且编译器还不够聪明,无法区分它们。所以它抛出了一个通用的、略显神秘的信息ORA-00907: missing right parenthesis,然后让我们去发现真正的灯笼裤。

发布的脚本有几个语法错误。首先,我将讨论触发 ORA-0097 的错误,但您需要将它们全部修复。

外键约束可以在引用列中声明,也可以在声明所有列之后在表级别声明。它们有不同的语法;您的脚本将两者混合在一起,这就是您获得 ORA-00907 的原因。

内联声明没有逗号,也不包括引用列名。

CREATE TABLE historys_T    (
    history_record    VARCHAR2 (8),
    customer_id       VARCHAR2 (8) 
          CONSTRAINT historys_T_FK FOREIGN KEY REFERENCES T_customers ON DELETE CASCADE,
    order_id           VARCHAR2 (10) NOT NULL,
          CONSTRAINT fk_order_id_orders REFERENCES orders ON DELETE CASCADE)

表级约束是一个单独的组件,因此有一个逗号并且确实提到了引用列。

CREATE TABLE historys_T    (
    history_record    VARCHAR2 (8),
    customer_id       VARCHAR2 (8),    
    order_id           VARCHAR2 (10) NOT NULL,
    CONSTRAINT historys_T_FK FOREIGN KEY (customer_id) REFERENCES T_customers ON DELETE CASCADE,   
   CONSTRAINT fk_order_id_orders FOREIGN KEY (order_id) REFERENCES orders ON DELETE CASCADE)

以下是其他语法错误的列表:

  1. 被引用的表(以及被引用的主键或唯一约束)必须已经存在,然后我们才能针对它们创建外键。因此,在创建引用表HISTORYS_T之前,您无法创建外键。ORDERS
  2. 您在某些外键子句 (LIBRARY_TFORMAT_T) 中拼错了引用表的名称。
  3. 您需要在 DEFAULT 子句中提供一个表达式。对于通常是当前日期的 DATE 列,DATE DEFAULT sysdate.

以冷静的眼光看待我们自己的代码是我们作为开发人员取得成功所需的一项技能。熟悉 Oracle 的文档确实很有帮助。将您的代码与 SQL 参考中的示例并排比较将帮助您在不到两天的时间内解决这些语法错误。在此处 (11g)此处 (12c)找到它。

除了语法错误,您的脚本还包含设计错误。这些不是失败,而是不应该成为习惯的不良做法。

  1. 您尚未命名大多数约束。Oracle 会给它们一个默认名称,但这将是一个可怕的名称,并使数据字典更难理解。明确命名每个约束有助于我们浏览物理数据库。当我们的 SQL 触发约束违规时,它还会导致更易于理解的错误消息。
  2. 一致地命名您的约束。有称为and的HISTORY_T约束,这两个都没有帮助。一个有用的约定是. 所以和分别。historys_T_FKfk_order_id_orders<child_table>_<parent_table>_fkhistory_customer_fkhistory_order_fk
  3. 使用单独的语句创建约束可能很有用。创建表然后主键然后外键将避免上面确定的依赖顺序问题。
  4. 您正在尝试在和之间创建循环外键。您可以通过在单独的语句中创建约束来做到这一点,但不要这样做:插入行时会遇到问题,删除时会出现更严重的问题。您应该重新考虑您的数据模型并找到一种方法来对两个表之间的关系进行建模,以便一个是父表,另一个是子表。或者您可能需要另一种关系,例如交集表。LIBRARY_TFORMATS
  5. 避免脚本中出现空行。有些工具会处理它们,但有些不会。我们可以配置 SQL*Plus 来处理它们,但最好避免这种需要。
  6. 的命名约定LIBRARY_T很丑陋。尝试找到一个不需要不必要的后缀的更具表现力的名称,以避免关键字冲突。
  7. T_CUSTOMERS更丑陋,既与您的其他表格不一致,又完全没有必要,因为customers它不是关键字。

命名事物是困难的。你不会相信这些年来我对表名的争论。最重要的是一致性。如果我查看数据字典并查看调用的表T_CUSTOMERSLIBRARY_T我的第一反应会是混乱。为什么这些表以不同的约定命名?这表达了什么 概念上的差异?所以,请决定一个命名约定并坚持下去。使您的表名全部单数或全部复数。尽量避免前缀和后缀;我们已经知道这是一张桌子,我们不需要 aT_或 a _TAB

于 2014-07-05T14:08:48.890 回答
5

我建议从您的CREATE TABLE语句中分离出所有外键约束。首先创建没有 FK 约束的所有表,然后在创建表后创建所有 FK 约束。

您可以使用 SQL 向表中添加 FK 约束,如下所示:

ALTER TABLE orders ADD CONSTRAINT orders_FK
  FOREIGN KEY (m_p_unique_id) REFERENCES library (m_p_unique_id);

特别是,您的表formatslibrary表都相互具有外键约束。创建这两个表的两个CREATE TABLE语句永远不会成功运行,因为每个语句只有在另一个表已经创建时才能工作。

分离约束创建允许您创建彼此具有 FK 约束的表。此外,如果您遇到约束错误,则只有该约束无法创建。目前,由于你的CREATE TABLE语句中的约束有错误,那么整个表创建失败并且你得到各种连锁错误,因为FK约束可能依赖于这些创建失败的表。

于 2014-07-04T22:04:14.827 回答
0

首先,在 histories_T 中,您正在引用表 T_customer(应该是 T_customers),其次,您缺少 REFERENCES 订购的 FOREIGN KEY 子句;不是使用您提供的代码创建(或删除)的。

也可能有其他错误,我承认 Oracle 从来都不擅长描述错误的原因——“变异表”就是一个很好的例子。

如果您还缺少其他问题,请告诉我。

于 2014-07-04T21:35:02.587 回答
0

尽管来自无用_T且拼写错误的历史。如果您使用SQL*Plus,它不接受在create table <name> (和列定义之间带有空新行的 create table 语句。

于 2014-07-04T21:19:06.097 回答