sql >> Database teknologi >  >> RDS >> Oracle

ORA-00907:manglende højre parentes

ORA-00907:manglende højre parentes

Dette er en af ​​flere generiske fejlmeddelelser, som angiver, at vores kode indeholder en eller flere syntaksfejl. Nogle gange kan det betyde, at vi bogstaveligt talt har udeladt en højre parentes; det er nemt nok at bekræfte, om vi bruger en editor, der har en match-parentes kapacitet (det gør de fleste teksteditorer rettet mod kodere). Men ofte betyder det, at compileren er stødt på et søgeord uden for kontekst. Eller måske er det et forkert stavet ord, et mellemrum i stedet for en understregning eller et manglende komma.

Desværre er de mulige årsager til, at vores kode ikke vil kompilere, praktisk talt uendelige, og compileren er bare ikke klog nok til at skelne dem. Så den sender en generisk, lidt kryptisk besked som ORA-00907: missing right parenthesis og overlader det til os at få øje på selve blomstringen.

Det udsendte script har flere syntaksfejl. Først vil jeg diskutere fejlen, der udløser den ORA-0097, men du bliver nødt til at rette dem alle.

Fremmednøglebegrænsninger kan erklæres på linje med referencekolonnen eller på tabelniveau, efter at alle kolonnerne er blevet erklæret. Disse har forskellige syntakser; dine scripts blander de to, og det er derfor, du får ORA-00907.

Indbygget erklæring har ikke et komma og inkluderer ikke referencekolonnens navn.

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)

Tabelniveaubegrænsninger er en separat komponent, og de har også et komma og nævner den refererende kolonne.

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)

Her er en liste over andre syntaksfejl:

  1. Den refererede tabel (og den refererede primærnøgle eller unikke begrænsning) skal allerede eksistere, før vi kan oprette en fremmednøgle mod dem. Så du kan ikke oprette en fremmednøgle til HISTORYS_T før du har oprettet den refererede ORDERS tabel.
  2. Du har stavet navnene på de refererede tabeller forkert i nogle af de fremmede nøgleudtryk (LIBRARY_T og FORMAT_T ).
  3. Du skal angive et udtryk i DEFAULT-udtrykket. For DATE-kolonner, der normalt er den aktuelle dato, DATE DEFAULT sysdate .

At se på vores egen kode med et koldt øje er en færdighed, vi alle skal opnå for at få succes som udviklere. Det hjælper virkelig at være bekendt med Oracles dokumentation. En side-by-side sammenligning af din kode og eksemplerne i SQL Reference ville have hjulpet dig med at løse disse syntaksfejl på betydeligt mindre end to dage. Find det her (11g) og her (12c).

Ud over syntaksfejl indeholder dine scripts designfejl. Det er ikke fejl, men dårlig praksis, som ikke bør blive til vaner.

  1. Du har ikke navngivet de fleste af dine begrænsninger. Oracle vil give dem et standardnavn, men det vil være et forfærdeligt navn og gør dataordbogen sværere at forstå. Eksplicit navngivning af hver begrænsning hjælper os med at navigere i den fysiske database. Det fører også til mere forståelige fejlmeddelelser, når vores SQL udløser en begrænsningsovertrædelse.
  2. Navngiv dine begrænsninger konsekvent. HISTORY_T har begrænsninger kaldet historys_T_FK og fk_order_id_orders , hvoraf ingen af ​​dem er nyttige. En nyttig konvention er <child_table>_<parent_table>_fk . Så history_customer_fk og history_order_fk hhv.
  3. Det kan være nyttigt at oprette begrænsningerne med separate udsagn. Oprettelse af tabeller og derefter primære nøgler og derefter fremmednøgler vil undgå problemerne med afhængighedsrækkefølge identificeret ovenfor.
  4. Du forsøger at oprette cykliske fremmednøgler mellem LIBRARY_T og FORMATS . Du kan gøre dette ved at oprette begrænsningerne i en separat erklæring, men gør det ikke:du vil få problemer med at indsætte rækker og endnu værre problemer med sletninger. Du bør genoverveje din datamodel og finde en måde at modellere forholdet mellem de to tabeller på, så den ene er forælderen og den anden barnet. Eller måske har du brug for en anden form for relation, såsom en skæringstabel.
  5. Undgå tomme linjer i dine scripts. Nogle værktøjer vil håndtere dem, men nogle vil ikke. Vi kan konfigurere SQL*Plus til at håndtere dem, men det er bedre at undgå behovet.
  6. Navnekonventionen for LIBRARY_T er grim. Prøv at finde et mere udtryksfuldt navn, som ikke kræver et unødvendigt suffiks for at undgå et søgeordssammenstød.
  7. T_CUSTOMERS er endnu grimmere, idet den både er inkonsistent med dine andre tabeller og fuldstændig unødvendig som customers er ikke et søgeord.

At navngive ting er svært. Du ville ikke tro de skænderier, jeg har haft om bordnavne gennem årene. Det vigtigste er konsistens. Hvis jeg ser på en dataordbog og ser tabeller kaldet T_CUSTOMERS og LIBRARY_T mit første svar ville være forvirring. Hvorfor er disse tabeller navngivet med forskellige konventioner? Hvilken konceptuel forskel udtrykker dette? Så vær venlig, beslut dig for en navnekonvention og hold dig til. Gør dine tabelnavne enten alle ental eller alle flertal. Undgå så vidt muligt præfikser og suffikser; vi ved allerede, at det er en tabel, vi behøver ikke en T_ eller en _TAB .



  1. SQLite JSON_INSERT()

  2. Django + Postgres + Large Time Series

  3. Konverter 'datetime' til 'smalldatetime' i SQL Server (T-SQL-eksempler)

  4. Hvordan bruger man MAX() på et underforespørgselsresultat?