ORA-00907:chybějící pravá závorka
Toto je jedna z několika obecných chybových zpráv, které indikují, že náš kód obsahuje jednu nebo více syntaktických chyb. Někdy to může znamenat, že jsme doslova vynechali pravou závorku; to je dostatečně snadné pro ověření, zda používáme editor, který má závorku schopnosti (většina textových editorů zaměřených na kodéry ano). Často to ale znamená, že kompilátor narazil na klíčové slovo vytržené z kontextu. Nebo je to možná špatně napsané slovo, mezera místo podtržítka nebo chybějící čárka.
Bohužel možných důvodů, proč se náš kód nezkompiluje, je prakticky nekonečno a kompilátor prostě není dostatečně chytrý, aby je rozlišil. Takže to vrhne obecnou, mírně záhadnou zprávu jako ORA-00907: missing right parenthesis
a nechává na nás, abychom odhalili skutečného kvetoucího.
Odeslaný skript obsahuje několik syntaktických chyb. Nejprve proberu chybu, která spouští ORA-0097, ale budete je muset všechny opravit.
Omezení cizího klíče lze deklarovat v souladu s odkazujícím sloupcem nebo na úrovni tabulky poté, co byly deklarovány všechny sloupce. Tyto mají různé syntaxe; vaše skripty kombinují obojí, a proto získáte ORA-00907.
Řádková deklarace neobsahuje čárku a neobsahuje název odkazujícího sloupce.
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)
Omezení na úrovni tabulky jsou samostatnou složkou, a proto mají čárku a zmiňují sloupec odkazu.
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)
Zde je seznam dalších syntaktických chyb:
- Odkazovaná tabulka (a odkazovaný primární klíč nebo jedinečné omezení) již musí existovat, než proti nim vytvoříme cizí klíč. Nemůžete tedy vytvořit cizí klíč pro
HISTORYS_T
než vytvoříte odkazovanéORDERS
stůl. - V některých klauzulích cizího klíče (
LIBRARY_T
) jste nesprávně napsali názvy tabulek, na které se odkazuje aFORMAT_T
). - Musíte zadat výraz v klauzuli DEFAULT. Pro sloupce DATE, které je obvykle aktuální datum,
DATE DEFAULT sysdate
.
Dívat se na vlastní kód chladným okem je dovednost, kterou všichni potřebujeme získat, abychom byli úspěšní jako vývojáři. Opravdu pomáhá seznámit se s dokumentací Oracle. Porovnání kódu vedle sebe a příkladů v SQL Reference by vám pomohlo vyřešit tyto syntaktické chyby za podstatně méně než dva dny. Najdete ho zde (11g) a zde (12c).
Kromě chyb syntaxe obsahují vaše skripty chyby v návrhu. To nejsou neúspěchy, ale špatné praktiky, které by se neměly stát návyky.
- Většinu svých omezení jste nepojmenovali. Oracle jim dá výchozí jméno, ale bude to příšerné a ztíží pochopení datového slovníku. Explicitní pojmenování každého omezení nám pomáhá orientovat se ve fyzické databázi. To také vede k srozumitelnějším chybovým zprávám, když naše SQL zakopne o porušení omezení.
- Pojmenujte svá omezení konzistentně.
HISTORY_T
má omezení nazvanáhistorys_T_FK
afk_order_id_orders
, z nichž ani jedno není užitečné. Užitečná konvence je<child_table>_<parent_table>_fk
. Takžehistory_customer_fk
ahistory_order_fk
respektive. - Může být užitečné vytvořit omezení pomocí samostatných příkazů. Vytváření tabulek, primárních klíčů a následně cizích klíčů zabrání výše uvedeným problémům s řazením závislostí.
- Pokoušíte se vytvořit cyklické cizí klíče mezi
LIBRARY_T
aFORMATS
. Můžete to udělat vytvořením omezení v samostatném příkazu, ale neudělejte to:budete mít problémy s vkládáním řádků a ještě horší problémy s mazáním. Měli byste přehodnotit svůj datový model a najít způsob, jak modelovat vztah mezi dvěma tabulkami tak, aby jedna byla nadřazená a druhá podřízená. Nebo možná potřebujete jiný druh vztahu, jako je průsečíková tabulka. - Ve skriptech se vyhněte prázdným řádkům. Některé nástroje si s nimi poradí, ale některé ne. Můžeme nakonfigurovat SQL*Plus, aby je zvládl, ale je lepší se tomu vyhnout.
- Konvence pojmenování knihovny
LIBRARY_T
je ošklivý. Pokuste se najít výraznější název, který nevyžaduje zbytečnou příponu, aby nedošlo ke střetu klíčových slov. T_CUSTOMERS
je ještě ošklivější, protože je nekonzistentní s ostatními tabulkami a jakocustomers
je zcela zbytečný není klíčové slovo.
Pojmenování věcí je těžké. Nevěřili byste, jaké hádky jsem měl za ta léta ohledně názvů stolů. Nejdůležitější je konzistence. Pokud se podívám do datového slovníku a uvidím tabulky s názvem T_CUSTOMERS
a LIBRARY_T
moje první odpověď by byl zmatek. Proč jsou tyto tabulky pojmenovány podle různých konvencí? Jaký pojmový rozdíl vyjadřuje toto? Takže, prosím, rozhodněte se pro konvenci pojmenování a držte se. Uveďte názvy tabulek buď v jednotném nebo množném čísle. Vyhněte se co nejvíce předponám a příponám; už víme, že je to tabulka, nepotřebujeme T_
nebo _TAB
.