ORA-00907: missing right parenthesis

后端 未结 4 1951
日久生厌
日久生厌 2020-12-06 04:52

I have been looking at this code for the past two days now and I can not seem to get it to work. It keeps giving me

ORA-00907: missing right pa

相关标签:
4条回答
  • 2020-12-06 05:27

    Firstly, in histories_T, you are referencing table T_customer (should be T_customers) and secondly, you are missing the FOREIGN KEY clause that REFERENCES orders; which is not being created (or dropped) with the code you provided.

    There may be additional errors as well, and I admit Oracle has never been very good at describing the cause of errors - "Mutating Tables" is a case in point.

    Let me know if there additional problems you are missing.

    0 讨论(0)
  • 2020-12-06 05:30

    ORA-00907: missing right parenthesis

    This is one of several generic error messages which indicate our code contains one or more syntax errors. Sometimes it may mean we literally have omitted a right bracket; that's easy enough to verify if we're using an editor which has a match bracket capability (most text editors aimed at coders do). But often it means the compiler has come across a keyword out of context. Or perhaps it's a misspelled word, a space instead of an underscore or a missing comma.

    Unfortunately the possible reasons why our code won't compile is virtually infinite and the compiler just isn't clever enough to distinguish them. So it hurls a generic, slightly cryptic, message like ORA-00907: missing right parenthesis and leaves it to us to spot the actual bloomer.

    The posted script has several syntax errors. First I will discuss the error which triggers that ORA-0097 but you'll need to fix them all.

    Foreign key constraints can be declared in line with the referencing column or at the table level after all the columns have been declared. These have different syntaxes; your scripts mix the two and that's why you get the ORA-00907.

    In-line declaration doesn't have a comma and doesn't include the referencing column name.

    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)
    

    Table level constraints are a separate component, and so do have a comma and do mention the referencing column.

    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)
    

    Here is a list of other syntax errors:

    1. The referenced table (and the referenced primary key or unique constraint) must already exist before we can create a foreign key against them. So you cannot create a foreign key for HISTORYS_T before you have created the referenced ORDERS table.
    2. You have misspelled the names of the referenced tables in some of the foreign key clauses (LIBRARY_T and FORMAT_T).
    3. You need to provide an expression in the DEFAULT clause. For DATE columns that is usually the current date, DATE DEFAULT sysdate.

    Looking at our own code with a cool eye is a skill we all need to gain to be successful as developers. It really helps to be familiar with Oracle's documentation. A side-by-side comparison of your code and the examples in the SQL Reference would have helped you resolved these syntax errors in considerably less than two days. Find it here (11g) and here (12c).

    As well as syntax errors, your scripts contain design mistakes. These are not failures, but bad practice which should not become habits.

    1. You have not named most of your constraints. Oracle will give them a default name but it will be a horrible one, and makes the data dictionary harder to understand. Explicitly naming every constraint helps us navigate the physical database. It also leads to more comprehensible error messages when our SQL trips a constraint violation.
    2. Name your constraints consistently. HISTORY_T has constraints called historys_T_FK and fk_order_id_orders, neither of which is helpful. A useful convention is <child_table>_<parent_table>_fk. So history_customer_fk and history_order_fk respectively.
    3. It can be useful to create the constraints with separate statements. Creating tables then primary keys then foreign keys will avoid the problems with dependency ordering identified above.
    4. You are trying to create cyclic foreign keys between LIBRARY_T and FORMATS. You could do this by creating the constraints in separate statement but don't: you will have problems when inserting rows and even worse problems with deletions. You should reconsider your data model and find a way to model the relationship between the two tables so that one is the parent and the other the child. Or perhaps you need a different kind of relationship, such as an intersection table.
    5. Avoid blank lines in your scripts. Some tools will handle them but some will not. We can configure SQL*Plus to handle them but it's better to avoid the need.
    6. The naming convention of LIBRARY_T is ugly. Try to find a more expressive name which doesn't require a needless suffix to avoid a keyword clash.
    7. T_CUSTOMERS is even uglier, being both inconsistent with your other tables and completely unnecessary, as customers is not a keyword.

    Naming things is hard. You wouldn't believe the wrangles I've had about table names over the years. The most important thing is consistency. If I look at a data dictionary and see tables called T_CUSTOMERS and LIBRARY_T my first response would be confusion. Why are these tables named with different conventions? What conceptual difference does this express? So, please, decide on a naming convention and stick to. Make your table names either all singular or all plural. Avoid prefixes and suffixes as much as possible; we already know it's a table, we don't need a T_ or a _TAB.

    0 讨论(0)
  • 2020-12-06 05:37

    Albeit from the useless _T and incorrectly spelled histories. If you are using SQL*Plus, it does not accept create table statements with empty new lines between create table <name> ( and column definitions.

    0 讨论(0)
  • 2020-12-06 05:40

    I would recommend separating out all of the foreign-key constraints from your CREATE TABLE statements. Create all the tables first without FK constraints, and then create all the FK constraints once you have created the tables.

    You can add an FK constraint to a table using SQL like the following:

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

    In particular, your formats and library tables both have foreign-key constraints on one another. The two CREATE TABLE statements to create these two tables can never run successfully, as each will only work when the other table has already been created.

    Separating out the constraint creation allows you to create tables with FK constraints on one another. Also, if you have an error with a constraint, only that constraint fails to be created. At present, because you have errors in the constraints in your CREATE TABLE statements, then entire table creation fails and you get various knock-on errors because FK constraints may depend on these tables that failed to create.

    0 讨论(0)
提交回复
热议问题