sql >> Database >  >> RDS >> Oracle

ORA-00907:rechter haakje ontbreekt

ORA-00907:rechter haakje ontbreekt

Dit is een van de verschillende generieke foutmeldingen die aangeven dat onze code een of meer syntaxisfouten bevat. Soms kan het betekenen dat we letterlijk een haakje rechts hebben weggelaten; dat is eenvoudig genoeg om te controleren of we een editor gebruiken die een match-haakje heeft mogelijkheid (de meeste teksteditors gericht op coders doen dat). Maar vaak betekent dit dat de compiler een zoekwoord uit de context is tegengekomen. Of misschien is het een verkeerd gespeld woord, een spatie in plaats van een onderstrepingsteken of een ontbrekende komma.

Helaas zijn de mogelijke redenen waarom onze code niet compileert vrijwel oneindig en de compiler is gewoon niet slim genoeg om ze te onderscheiden. Dus het slingert een generiek, enigszins cryptisch bericht als ORA-00907: missing right parenthesis en laat het aan ons over om de echte bloeier te spotten.

Het geposte script bevat verschillende syntaxisfouten. Eerst zal ik de fout bespreken die die ORA-0097 veroorzaakt, maar je moet ze allemaal oplossen.

Foreign key-beperkingen kunnen worden gedeclareerd in overeenstemming met de verwijzende kolom of op tabelniveau nadat alle kolommen zijn gedeclareerd. Deze hebben verschillende syntaxis; je scripts combineren de twee en daarom krijg je de ORA-00907.

In-line declaratie heeft geen komma en bevat niet de verwijzende kolomnaam.

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)

Beperkingen op tabelniveau zijn een afzonderlijk onderdeel, en hebben dus een komma en vermelden wel de verwijzende kolom.

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)

Hier is een lijst met andere syntaxisfouten:

  1. De tabel waarnaar wordt verwezen (en de primaire sleutel of unieke beperking waarnaar wordt verwezen) moet al bestaan ​​voordat we er een externe sleutel voor kunnen maken. U kunt dus geen externe sleutel maken voor HISTORYS_T voordat u de ORDERS waarnaar wordt verwezen heeft gemaakt tafel.
  2. Je hebt de namen van de tabellen waarnaar wordt verwezen verkeerd gespeld in sommige clausules van de refererende sleutel (LIBRARY_T en FORMAT_T ).
  3. U moet een expressie opgeven in de DEFAULT-clausule. Voor DATE-kolommen is dat meestal de huidige datum, DATE DEFAULT sysdate .

Met een koel oog naar onze eigen code kijken, is een vaardigheid die we allemaal moeten verwerven om als ontwikkelaars succesvol te zijn. Het helpt echt om bekend te zijn met de documentatie van Oracle. Een zij-aan-zij vergelijking van uw code en de voorbeelden in de SQL Reference zou u hebben geholpen deze syntaxisfouten in aanzienlijk minder dan twee dagen op te lossen. Vind het hier (11g) en hier (12c).

Naast syntaxisfouten bevatten uw scripts ontwerpfouten. Dit zijn geen mislukkingen, maar slechte praktijken die geen gewoontes zouden moeten worden.

  1. Je hebt de meeste van je beperkingen niet genoemd. Oracle zal ze een standaardnaam geven, maar het zal een afschuwelijke naam zijn en het datadictionary moeilijker te begrijpen maken. Door elke beperking expliciet te noemen, kunnen we door de fysieke database navigeren. Het leidt ook tot begrijpelijker foutmeldingen wanneer onze SQL een schending van een beperking uitvoert.
  2. Benoem uw beperkingen consequent. HISTORY_T heeft beperkingen genaamd historys_T_FK en fk_order_id_orders , geen van beide is nuttig. Een handige conventie is <child_table>_<parent_table>_fk . Dus history_customer_fk en history_order_fk respectievelijk.
  3. Het kan handig zijn om de beperkingen met aparte instructies te maken. Door tabellen te maken en vervolgens primaire sleutels en vervolgens externe sleutels, worden de hierboven genoemde problemen met de volgorde van afhankelijkheid vermeden.
  4. U probeert cyclische externe sleutels te maken tussen LIBRARY_T en FORMATS . Je zou dit kunnen doen door de beperkingen in een aparte verklaring te maken, maar doe dat niet:je zult problemen hebben bij het invoegen van rijen en nog erger problemen met verwijderingen. U moet uw gegevensmodel heroverwegen en een manier vinden om de relatie tussen de twee tabellen te modelleren, zodat de ene de ouder is en de andere de onderliggende. Of misschien heb je een ander soort relatie nodig, zoals een intersectietabel.
  5. Vermijd lege regels in uw scripts. Sommige tools kunnen ze aan, maar andere niet. We kunnen SQL*Plus configureren om ze te verwerken, maar het is beter om de noodzaak te vermijden.
  6. De naamgevingsconventie van LIBRARY_T is lelijk. Probeer een meer expressieve naam te vinden die geen onnodig achtervoegsel nodig heeft om een ​​trefwoordconflict te voorkomen.
  7. T_CUSTOMERS is nog lelijker, omdat het zowel inconsistent is met je andere tafels als volkomen onnodig, als customers is geen trefwoord.

Dingen benoemen is moeilijk. Je zou de ruzies die ik in de loop der jaren heb gehad over tafelnamen niet geloven. Het belangrijkste is consistentie. Als ik naar een datadictionary kijk en tabellen zie met de naam T_CUSTOMERS en LIBRARY_T mijn eerste reactie zou verwarring zijn. Waarom worden deze tabellen met verschillende conventies genoemd? Welk conceptueel verschil drukt dit uit? Dus, alsjeblieft, beslis over een naamgevingsconventie en houd je eraan. Maak uw tabelnamen ofwel allemaal enkelvoud of allemaal meervoud. Vermijd voor- en achtervoegsels zoveel mogelijk; we weten al dat het een tafel is, we hebben geen T_ nodig of een _TAB .



  1. Snapshots van SQL Server-database -1

  2. Fix:“operator bestaat niet:geheel getal || geheel getal” in PostgreSQL

  3. Converteer tijdstempel naar datum in Oracle SQL

  4. Kan offset-naïeve en offset-bewuste datetimes niet aftrekken