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
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.
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:
HISTORYS_T
before you have created the referenced ORDERS
table.LIBRARY_T
and FORMAT_T
). 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.
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.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.LIBRARY_T
is ugly. Try to find a more expressive name which doesn't require a needless suffix to avoid a keyword clash.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
.
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.
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.