Oracle
 sql >> база данни >  >> RDS >> Oracle

ORA-00907:липсва дясна скоба

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_T и FORMAT_T ).
  3. Трябва да предоставите израз в клаузата DEFAULT. За колони DATE, която обикновено е текущата дата, DATE DEFAULT sysdate .

Гледането на собствения си код с хладно око е умение, което всички трябва да придобием, за да бъдем успешни като разработчици. Наистина е полезно да сте запознати с документацията на Oracle. Едно до друго сравнение на вашия код и примерите в SQL Reference би ви помогнало да разрешите тези синтактични грешки за значително по-малко от два дни. Намерете го тук (11g) и тук (12c).

Освен синтактични грешки, вашите скриптове съдържат грешки в дизайна. Това не са неуспехи, а лоша практика, която не трябва да става навик.

  1. Не сте посочили повечето от ограниченията си. Oracle ще им даде име по подразбиране, но то ще бъде ужасно и ще направи речника на данните по-труден за разбиране. Изричното именуване на всяко ограничение ни помага да навигираме във физическата база данни. Това също води до по-разбираеми съобщения за грешки, когато нашият SQL изключи нарушение на ограничението.
  2. Именувайте ограниченията си последователно. HISTORY_T има ограничения, наречени historys_T_FK и fk_order_id_orders , нито едно от двете не е полезно. Полезна конвенция е <child_table>_<parent_table>_fk . Така че history_customer_fk и history_order_fk съответно.
  3. Може да бъде полезно да създадете ограничения с отделни изрази. Създаването на таблици, след това първични ключове и след това външни ключове ще избегне проблемите с подреждането на зависимостите, посочени по-горе.
  4. Опитвате се да създадете циклични външни ключове между LIBRARY_T и FORMATS . Можете да направите това, като създадете ограниченията в отделен оператор, но не го правете:ще имате проблеми при вмъкване на редове и дори по-лоши проблеми с изтриванията. Трябва да преразгледате своя модел на данни и да намерите начин да моделирате връзката между двете таблици, така че едната да е родител, а другата дете. Или може би имате нужда от различен вид връзка, като например пресечна таблица.
  5. Избягвайте празни редове във вашите скриптове. Някои инструменти ще се справят с тях, но някои не. Можем да конфигурираме SQL*Plus да се справя с тях, но е по-добре да избегнем необходимостта.
  6. Конвенцията за именуване на LIBRARY_T е грозен. Опитайте се да намерите по-изразително име, което не изисква ненужен суфикс, за да избегнете сблъсък на ключови думи.
  7. T_CUSTOMERS е още по-грозен, тъй като е едновременно несъвместим с другите ви таблици и напълно ненужен като customers не е ключова дума.

Наименуването на нещата е трудно. Няма да повярвате в споровете, които съм имал за имената на таблици през годините. Най-важното е последователността. Ако погледна речник с данни и видя таблици, наречени T_CUSTOMERS и LIBRARY_T първият ми отговор би бил объркване. Защо тези таблици са наречени с различни конвенции? Какваконцептуална разлика това изразява ли се? Така че, моля, вземете решение за конвенция за именуване и се придържайте към нея. Направете имената на вашите таблици в единствено или множествено число. Избягвайте доколкото е възможно представки и суфикси; вече знаем, че е маса, не ни трябва T_ или _TAB .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dynamic Oracle Pivot_In_Clause

  2. Сравнение на доставчици, съвместими с Entity Framework за Oracle?

  3. Защо PL/SQL не зачита привилегиите, предоставени от ролите?

  4. проблем с функцията to_date със sysdate

  5. Как да напиша скрипт за вмъкване на оракул с едно поле като CLOB?