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 parenthesis
.
I know that this is a topic that comes up a lot but for some reason none of the examples I have seen has helped me. Can someone please tell me why I got this error and how do I fix it? I am pretty sure that it has nothing to do with my parenthesis, maybe it’s my CONSTRAINTS?
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);
Here are the results I get when I run the code:
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.
I can’t seem to figure out why this error is occurring.
Here is my code:
SELECT DISTINCT c.cid
FROM customers c
WHERE EXISTS ( SELECT DISTINCT t.aid
FROM transactions t
WHERE EXISTS ( SELECT a.balance
FROM accounts a
WHERE t.cid = c.cid
AND a.aid = t.aid
AND ((sysdate - a.date_opened) > 365)
ORDER BY a.balance DESC
)
);
The error is in the last line.
asked Nov 19, 2012 at 3:07
3
There are 2 issues:
- You can’t reference table from subquery which is not a direct parent level — a subquery inside
EXISTS
does not see a tablec
, so conditiont.cid = c.cid
is wrong - I don’t see any meaning in
ORDER BY
insideEXISTS
subquery. It also can be illegal, but I’m not sure.
I advise you to rewrite query from 2 EXISTS
into 2 JOINS
. It would be like:
SELECT cid
FROM (SELECT c.cid, a.balance
FROM customers c,
accounts a,
transactions t
WHERE t.cid = c.cid
AND a.aid = t.aid
AND sysdate - a.date_opened > 365)
ORDER BY balance DESC
answered Dec 26, 2012 at 6:16
PavelPavel
1515 bronze badges
Side note: Your subquery is going to require a full table scan on accounts
, even if you have an index on date_opened
, because you are doing math in the WHERE clause.
For every row, Oracle has to evaluate this expression:
((sysdate - a.date_opened) > 365)
to take the value of sysdate
and subtract the date opened and then compare it to 365. It has to check each row individually.
However, if you algebraically change that expression to
sysdate - 365 > a.date_opened
then it only has to evaluate the expression sysdate-365
once, at the beginning of the query, and can then compare that to a.date_opened
and use the index for an index scan.
answered Dec 26, 2012 at 7:10
Andy LesterAndy Lester
91.1k13 gold badges101 silver badges152 bronze badges
you are doing mistake in AND ((sysdate — a.date_opened) > 365)
use like this :-
AND (sysdate — a.date_opened) > 365
answered Dec 26, 2012 at 6:28
Did you get an ORA-00907: missing right parenthesis error? Learn what caused it and how to resolve it in this article.
ORA-00907 Cause
When working with Oracle SQL, all left parenthesis (the “(” character) must be paired with a right parenthesis character (the “)” character).
If there are more left parentheses than right parentheses, then you’ll get this error.
It can also be caused by syntax errors in your CREATE TABLE statement.
There are a few ways to resolve this error.
Solution 1 – Check Your Pairs of Parentheses
The first solution is to check that you have the correct number of parentheses.
If you’re using an IDE such as SQL Developer, you can put your cursor next to each parenthesis to see where the matching parenthesis is. If it’s in the right spot, great. If the match is showing up somewhere unexpected, then you’re missing a parenthesis.
This can often happen if you’re using nested functions.
While you’re here, if you want an easy-to-use list of the main features in Oracle SQL, get my SQL Cheat Sheet here:
Solution 2 – Check your CREATE TABLE Statement
If you get an ORA-00907 error when running a CREATE TABLE statement, it could be because of an incorrect reference to a foreign key.
For example:
CREATE TABLE order_test (
order_id NUMBER NOT NULL PRIMARY KEY,
order_date DATE NOT NULL,
customer_id NUMBER FOREIGN KEY REFERENCES customer(customer_id)
);
Result:
Error starting at line : 3 in command - CREATE TABLE order_test ( order_id NUMBER NOT NULL PRIMARY KEY, order_date DATE NOT NULL, customer_id NUMBER FOREIGN KEY REFERENCES customer(customer_id) ) Error report - SQL Error: ORA-00907: missing right parenthesis 00907. 00000 - "missing right parenthesis" *Cause: *Action:
This happens because we don’t need to have the words FOREIGN KEY when defining a foreign key inline (like we have here).
We can either:
- Remove the words FOREIGN KEY
- Declare the foreign key out of line (recommended)
Option A:
If you want to keep using the inline declaration, remove the words FOREIGN KEY:
CREATE TABLE order_test (
order_id NUMBER NOT NULL PRIMARY KEY,
order_date DATE NOT NULL,
customer_id NUMBER REFERENCES customer(customer_id)
);
The issue with this approach is you don’t know the name of the foreign key, which can make maintenance harder.
It’s better to declare a foreign key on a different line and give it a specific name.
Option B:
Declare the foreign key with a name
CREATE TABLE order_test_prefer (
order_id NUMBER NOT NULL PRIMARY KEY,
order_date DATE NOT NULL,
customer_id NUMBER NOT NULL,
CONSTRAINT fk_order_customer FOREIGN KEY (customer_id)
REFERENCES customer (customer_id)
);
This way, you can have the fk_order_customer as the constraint name, and can easily see and refer to it.
For a full guide on using the CREATE TABLE statement, including the syntax for Oracle, read my guide here.
Make sure your CREATE TABLE statement aligns with this syntax, and you shouldn’t have any issues.
So, that’s how you resolve the ORA-00907: missing right parenthesis error.
While you’re here, if you want an easy-to-use list of the main features in Oracle SQL, get my SQL Cheat Sheet here:
При использовании коррелированных подзапросов, т.е. подзапросов, результаты которых используются для каждой строки основного запроса — «a correlated subquery is evaluated once for each row», могут встречаются ошибки, неточно объясняющие, что делается неправильно
ora-904 «%s: invalid identifier»
SQL> select (select count(*) from (select * from scott.emp where ename = dual.dummy)) from dual; select (select count(*) from (select * from scott.emp where ename = dual.dummy)) from dual * ERROR at line 1: ORA-00904: "DUAL"."DUMMY": invalid identifier
ora-907 «missing right parenthesis»
SQL> select (select empno from scott.emp where ename = dual.dummy order by 1) from dual; select (select empno from scott.emp where ename = dual.dummy order by 1) from dual * ERROR at line 1: ORA-00907: missing right parenthesis
Первая ошибка ora-904 в случае correlated subquery при отсутствии синтаксических ошибок сообщает об использовании более, чем одного уровня глубины вложенности (N-th level sub-query):
SQL> select (select count(*) from (select * from scott.emp where ename = dual.dummy)) from dual; select (select count(*) from (select * from scott.emp where ename = dual.dummy)) from dual * ERROR at line 1: ORA-00904: "DUAL"."DUMMY": invalid identifier
что не поддерживается Oracle (до версии 11.1.0.7 включительно) и стандартом SQL: ANSI SQL has table references (correlation names) scoped to just one level deep. Это пишет вице-президент Oracle T.Kyte, отвечая на соответствующий вопрос «Is there some sort of nesting limit for correlated subqueries?», т.е. информация официальная, из первых рук, пример оттуда же. В документации Oracle, начиная с 10.1, пишется иначе:
Oracle performs a correlated subquery when a nested subquery references a column from a table referred to a parent statement any number of levels above the subquery
— но, это, видимо, долгосрочные планы Oracle.
ora-907
SQL> select (select empno from scott.emp where ename = dual.dummy order by 1) from dual; select (select empno from scott.emp where ename = dual.dummy order by 1) from dual * ERROR at line 1: ORA-00907: missing right parenthesis
тут проблема старая и известная: запрет на использование ORDER BY в подзапросах, описанная в документации Oracle 7 (в документации следующих версий уже не упоминается — видимо, тоже есть планы по исправлению):
The ORDER BY clause cannot appear in subqueries within other statements.
По вышеупомянутой ссылке на сайте asktom.oracle.com можно найти пример замены конструкции с ORDER BY типа:
(SELECT column_1 FROM (SELECT column_1 FROM table_1 WHERE ... ORDER BY ...) Q_1 WHERE rownum = 1)
на аналитическую функцию типа :
(SELECT max(column_1) keep (dense_rank first ORDER BY ...) FROM table_1 WHERE ...)
для одновременного понижения уровня вложенности подзапроса (correlated query level deep) до 1 и устранения проблемы с ORDER BY в подзапросе — конструкция dense_rank first ORDER BY допускается Oracle.
Комментарии к записи ora-904 ora-907 при использовании коррелированных подзапросов отключены
bestage 0 / 0 / 0 Регистрация: 26.04.2014 Сообщений: 24 |
||||
1 |
||||
30.05.2014, 10:57. Показов 23148. Ответов 9 Метки нет (Все метки)
вот создаю таблицу из примера Грубера, выдает ошибку, хотя в упор не вижу где она
0 |
mlc 25 / 25 / 10 Регистрация: 20.09.2009 Сообщений: 110 |
||||||||
30.05.2014, 11:05 |
2 |
|||||||
Сообщение было отмечено bestage как решение Решениеу типа данных INT[EGER] нет таких параметров как precision, scale. Поэтому правильно будет так
либо так
1 |
0 / 0 / 0 Регистрация: 26.04.2014 Сообщений: 24 |
|
30.05.2014, 11:22 [ТС] |
3 |
спасибо, заработало Добавлено через 10 минут ————————————————
0 |
Grossmeister Модератор 4214 / 3054 / 582 Регистрация: 21.01.2011 Сообщений: 13,205 |
||||
30.05.2014, 11:31 |
4 |
|||
потом как вносить их туда командой insert
PS
0 |
0 / 0 / 0 Регистрация: 26.04.2014 Сообщений: 24 |
|
30.05.2014, 11:40 [ТС] |
5 |
я понял, а при создании таблицы, это поле odate как правильно обьвлять?
0 |
Grossmeister Модератор 4214 / 3054 / 582 Регистрация: 21.01.2011 Сообщений: 13,205 |
||||
30.05.2014, 11:43 |
6 |
|||
это поле odate как правильно обьвлять Так и объявлять
0 |
0 / 0 / 0 Регистрация: 26.04.2014 Сообщений: 24 |
|
30.05.2014, 15:22 [ТС] |
7 |
а вот как обьявлять десятичные числа чтобы после точки было 2 знака? я обьявил флоат — там округлило до одного знака, и еще формат даты поставил дд\мм\гггг, переставило месяцы и дни местами. блин, и скрин как по человечески загрузить?))
0 |
25 / 25 / 10 Регистрация: 20.09.2009 Сообщений: 110 |
|
30.05.2014, 15:29 |
8 |
а вот как объявлять десятичные числа чтобы после точки было 2 знака? используйте number, как советовал Grossmeister. Например number(4,2). За отображение даты в определенном формате отвечают nls настройки.
1 |
Модератор 4214 / 3054 / 582 Регистрация: 21.01.2011 Сообщений: 13,205 |
|
30.05.2014, 15:33 |
9 |
а вот как обьявлять десятичные числа чтобы после точки было 2 знака? Я уже сказал, что в Oracle для числового типа используется NUMBER. Если задашь просто NUMBER, то число знаков после запятой будет по дефолту. Если нужно не больше 2, тогда NUMBER(…, 2).
еще формат даты поставил дд\мм\гггг, переставило месяцы и дни местами. Не понял, где ты поставил формат даты. Как вставлять дату в БД, я уже показал.
1 |
0 / 0 / 0 Регистрация: 26.04.2014 Сообщений: 24 |
|
30.05.2014, 15:41 [ТС] |
10 |
спасибо, разобрался
0 |