sql >> Databasteknik >  >> RDS >> Oracle

ORA-00907:höger parentes saknas

ORA-00907:höger parentes saknas

Detta är ett av flera allmänna felmeddelanden som indikerar att vår kod innehåller ett eller flera syntaxfel. Ibland kan det betyda att vi bokstavligen har utelämnat en höger parentes; det är lätt nog att verifiera om vi använder en redigerare som har en matchningsparentes förmåga (de flesta textredigerare som är riktade till kodare gör det). Men ofta betyder det att kompilatorn har stött på ett nyckelord ur sitt sammanhang. Eller så kanske det är ett felstavat ord, ett mellanslag istället för ett understreck eller ett kommatecken.

Tyvärr är de möjliga orsakerna till att vår kod inte kommer att kompilera praktiskt taget oändliga och kompilatorn är helt enkelt inte smart nog att skilja dem åt. Så det sänder ett allmänt, lite kryptiskt meddelande som ORA-00907: missing right parenthesis och överlåter åt oss att upptäcka själva blomningen.

Det upplagda skriptet har flera syntaxfel. Först kommer jag att diskutera felet som utlöser den där ORA-0097 men du måste fixa dem alla.

Utländska nyckelbegränsningar kan deklareras i linje med referenskolumnen eller på tabellnivå efter att alla kolumner har deklarerats. Dessa har olika syntaxer; dina skript blandar de två och det är därför du skaffar ORA-00907.

In-line-deklarationen har inget kommatecken och innehåller inte referenskolumnnamnet.

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)

Tabellnivåbegränsningar är en separat komponent, och har därför ett kommatecken och nämner referenskolumnen.

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)

Här är en lista över andra syntaxfel:

  1. Den refererade tabellen (och den refererade primärnyckeln eller unika begränsningen) måste redan existera innan vi kan skapa en främmande nyckel mot dem. Så du kan inte skapa en främmande nyckel för HISTORYS_T innan du har skapat den refererade ORDERS tabell.
  2. Du har stavat namnen på de refererade tabellerna fel i några av de främmande nyckelsatserna (LIBRARY_T och FORMAT_T ).
  3. Du måste ange ett uttryck i DEFAULT-satsen. För DATE-kolumner som vanligtvis är det aktuella datumet, DATE DEFAULT sysdate .

Att titta på vår egen kod med ett kallt öga är en färdighet vi alla behöver skaffa oss för att bli framgångsrika som utvecklare. Det hjälper verkligen att vara bekant med Oracles dokumentation. En jämförelse sida vid sida av din kod och exemplen i SQL Reference skulle ha hjälpt dig att lösa dessa syntaxfel på betydligt mindre än två dagar. Hitta den här (11g) och här (12c).

Förutom syntaxfel innehåller dina skript designfel. Dessa är inte misslyckanden, utan dålig praxis som inte bör bli vanor.

  1. Du har inte nämnt de flesta av dina begränsningar. Oracle kommer att ge dem ett standardnamn men det kommer att vara ett hemskt namn och gör dataordboken svårare att förstå. Att uttryckligen namnge varje begränsning hjälper oss att navigera i den fysiska databasen. Det leder också till mer begripliga felmeddelanden när vår SQL löser en begränsningsöverträdelse.
  2. Namn dina begränsningar konsekvent. HISTORY_T har begränsningar som kallas historys_T_FK och fk_order_id_orders , vilket inte är till hjälp. En användbar konvention är <child_table>_<parent_table>_fk . Så history_customer_fk och history_order_fk respektive.
  3. Det kan vara användbart att skapa begränsningarna med separata satser. Genom att skapa tabeller och sedan primärnycklar och sedan främmande nycklar undviker du problemen med beroendeordning som identifierats ovan.
  4. Du försöker skapa cykliska främmande nycklar mellan LIBRARY_T och FORMATS . Du kan göra detta genom att skapa begränsningarna i separata uttalanden men gör det inte:du kommer att få problem när du infogar rader och ännu värre problem med borttagningar. Du bör ompröva din datamodell och hitta ett sätt att modellera förhållandet mellan de två tabellerna så att den ena är föräldern och den andra barnet. Eller så kanske du behöver en annan typ av relation, till exempel en skärningstabell.
  5. Undvik tomma rader i dina skript. Vissa verktyg kommer att hantera dem men andra inte. Vi kan konfigurera SQL*Plus för att hantera dem, men det är bättre att undvika behovet.
  6. Namnkonventionen för LIBRARY_T är ful. Försök att hitta ett mer uttrycksfullt namn som inte kräver ett onödigt suffix för att undvika en sökordskrock.
  7. T_CUSTOMERS är ännu fulare, är både inkonsekvent med dina andra tabeller och helt onödigt, som customers är inte ett sökord.

Att namnge saker är svårt. Du skulle inte tro de bråk jag har haft om bordsnamn genom åren. Det viktigaste är konsekvens. Om jag tittar på en dataordbok och ser tabeller som heter T_CUSTOMERS och LIBRARY_T mitt första svar skulle vara förvirring. Varför namnges dessa tabeller med olika konventioner? Vilken konceptuell skillnad uttrycker detta? Så snälla, bestäm dig för en namnkonvention och håll dig till. Gör dina tabellnamn till antingen singular eller plural. Undvik prefix och suffix så mycket som möjligt; vi vet redan att det är en tabell, vi behöver ingen T_ eller en _TAB .



  1. Sammanfoga många rader till en enda textsträng med gruppering

  2. SQL Server:Isolationsnivå läcker över poolade anslutningar

  3. Hur tar man bort de 1000 översta raderna från en tabell med SQL Server 2008?

  4. Den repeterbara läsisoleringsnivån