Undantagshantering in Oracle PL/SQL (exempel)
Vad är undantagshantering i PL/SQL?
Ett undantag uppstår när PL/SQL-motorn stöter på en instruktion som den inte kan exekvera på grund av ett fel som uppstår vid körning. Dessa fel kommer inte att fångas upp vid tidpunkten för kompileringen och därför behövs dessa endast hanteras under körningen.
Till exempel, om PL/SQL-motorn får en instruktion att dividera valfritt tal med '0', kommer PL/SQL-motorn att kasta det som ett undantag. Undantaget höjs endast under körtiden av PL/SQL-motorn.
Undantag kommer att stoppa programmet från att köras ytterligare, så för att undvika sådana tillstånd måste de fångas in och hanteras separat. Denna process kallas Exception-Handling, där programmeraren hanterar undantaget som kan inträffa under körningstiden.
Syntax för undantagshantering
Undantag hanteras på blocknivå, dvs en gång om något undantag inträffar i något block så kommer kontrollen att komma ur exekveringsdelen av det blocket. Undantaget kommer då att hanteras vid undantagshanteringsdelen av det blocket. Efter att ha hanterat undantaget är det inte möjligt att skicka tillbaka kontrollen tillbaka till exekveringsdelen av det blocket.
Syntaxen nedan förklarar hur man fångar och hanterar undantaget.
BEGIN <execution block> . . EXCEPTION WHEN <exceptionl_name> THEN <Exception handling code for the “exception 1 _name’' > WHEN OTHERS THEN <Default exception handling code for all exceptions > END;
Syntaxförklaring:
- I ovanstående syntax innehåller undantagshanteringsblocket serier av WHEN-villkor för att hantera undantaget.
- Varje WHEN-villkor följs av undantagsnamnet som förväntas höjas under körningstiden.
- När något undantag höjs under körning, kommer PL/SQL-motorn att leta i undantagshanteringsdelen för just det undantaget. Den kommer att börja från den första 'WHEN'-satsen och i följd kommer den att söka.
- Om den hittade undantagshanteringen för undantaget som har tagits upp, kommer den att exekvera den specifika hanteringskoddelen.
- Om ingen av "WHEN"-satsen finns för undantaget som har tagits upp, kommer PL/SQL-motorn att köra delen "WHEN OTHERS" (om sådan finns). Detta är vanligt för alla undantag.
- Efter exekvering av undantaget kommer delkontrollen att gå ut ur det aktuella blocket.
- Endast en undantagsdel kan exekveras för ett block vid körning. Efter att ha utfört den kommer styrenheten att hoppa över den återstående undantagshanteringsdelen och kommer att gå ut ur det aktuella blocket.
Obs: NÄR ANDRA ska alltid vara på den sista positionen i sekvensen. Undantagshanteringsdelen som finns efter WHEN OTHERS kommer aldrig att exekveras eftersom kontrollen kommer att lämna blocket efter exekvering av WHEN OTHERS.
Typer av undantag
Det finns två typer av undantag i Pl/SQL.
- Fördefinierade undantag
- Användardefinierat undantag
Fördefinierade undantag
Oracle har fördefinierat något vanligt undantag. Dessa undantag har ett unikt undantagsnamn och felnummer. Dessa undantag är redan definierade i 'STANDARD'-paketet i Oracle. I kod kan vi direkt använda dessa fördefinierade undantagsnamn för att hantera dem.
Nedan finns några fördefinierade undantag
undantag | Felkod | Undantag Anledning |
---|---|---|
ACCESS_INTO_NULL | ORA-06530 | Tilldela ett värde till attributen för oinitierade objekt |
CASE_NOT_FOUND | ORA-06592 | Ingen av "WHEN"-satsen i CASE-satsen är uppfylld och ingen "ELSE"-sats är specificerad |
COLLECTION_IS_NULL | ORA-06531 | Använda insamlingsmetoder (förutom FINNS) eller komma åt samlingsattribut på en oinitierad samling |
CURSOR_ALREADY_OPEN | ORA-06511 | Försöker öppna en markören som redan är öppnad |
DUP_VAL_ON_INDEX | ORA-00001 | Lagra ett dubblettvärde i en databaskolumn som är ett begränsat av unikt index |
INVALID_CURSOR | ORA-01001 | Olagliga marköroperationer som att stänga en oöppnad markör |
OGILTIGT NUMMER | ORA-01722 | Konvertering av tecken till ett nummer misslyckades på grund av ogiltigt siffertecken |
INGEN INFORMATION HITTAD | ORA-01403 | När 'SELECT'-satsen som innehåller INTO-satsen hämtar inga rader. |
ROW_MISMATCH | ORA-06504 | När markörvariabeldatatypen är inkompatibel med den faktiska markörreturtypen |
SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Refererar samling med ett indexnummer som är större än samlingsstorleken |
SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Refererar insamling med ett indexnummer som ligger utanför det lagliga intervallet (t.ex.: -1) |
TOO_MANY_ROWS | ORA-01422 | När en 'SELECT'-sats med INTO-sats returnerar mer än en rad |
VALUE_ERROR | ORA-06502 | Aritmetiskt eller storleksbegränsningsfel (t.ex. att tilldela ett värde till en variabel som är större än variabelstorleken) |
ZERO_DIVIDE | ORA-01476 | Dividera ett tal med '0' |
Användardefinierat undantag
In Oracle, förutom de ovan fördefinierade undantagen, kan programmeraren skapa sina egna undantag och hantera dem. De kan skapas på delprogramnivå i deklarationsdelen. Dessa undantag är endast synliga i det underprogrammet. Undantaget som definieras i paketspecifikationen är offentligt undantag, och det är synligt varhelst paketet är tillgängligt.
Syntax: På underprogramsnivå
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- I ovanstående syntax är variabeln 'exception_name' definierad som 'EXCEPTION' typ.
- Detta kan användas som på ett liknande sätt som ett fördefinierat undantag.
Syntax:På paketspecifikationsnivå
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- I ovanstående syntax är variabeln 'exception_name' definierad som 'EXCEPTION'-typen i paketspecifikationen för .
- Detta kan användas i databasen varhelst paketet 'paketnamn' kan anropas.
PL/SQL-höjningsundantag
Alla fördefinierade undantag höjs implicit när felet inträffar. Men de användardefinierade undantagen måste höjas uttryckligen. Detta kan uppnås med hjälp av nyckelordet 'RAISE'. Detta kan användas på något av de sätt som nämns nedan.
Om 'RAISE' används separat i programmet, kommer det att sprida det redan upphöjda undantaget till det överordnade blocket. Endast i undantagsblock kan användas som visas nedan.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
Syntaxförklaring:
- I ovanstående syntax används nyckelordet RAISE i undantagshanteringsblocket.
- Närhelst programmet stöter på undantaget "exception_name", hanteras undantaget och kommer att slutföras normalt
- Men nyckelordet 'RAISE' i undantagshanteringsdelen kommer att sprida detta särskilda undantag till det överordnade programmet.
Obs: När du höjer undantaget till det överordnade blocket bör undantaget som höjs också vara synligt vid det överordnade blocket, annars kommer oracle att ge ett fel.
- Vi kan använda nyckelordet 'RAISE' följt av undantagsnamnet för att höja det specifika användardefinierade/fördefinierade undantaget. Detta kan användas i både exekveringsdelen och i undantagshanteringsdelen för att höja undantaget.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
Syntaxförklaring:
- I ovanstående syntax används nyckelordet RAISE i exekveringsdelen följt av undantaget "exception_name".
- Detta kommer att ta upp detta särskilda undantag vid tidpunkten för verkställandet, och detta måste hanteras eller höjas ytterligare.
Exempelvis 1: I det här exemplet ska vi se
- Hur man förklarar undantaget
- Hur man höjer det deklarerade undantaget och
- Hur man sprider det till huvudblocket
DECLARE Sample_exception EXCEPTION; PROCEDURE nested_block IS BEGIN Dbms_output.put_line(‘Inside nested block’); Dbms_output.put_line(‘Raising sample_exception from nested block’); RAISE sample_exception; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line (‘Exception captured in nested block. Raising to main block’); RAISE, END; BEGIN Dbms_output.put_line(‘Inside main block’); Dbms_output.put_line(‘Calling nested block’); Nested_block; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line (‘Exception captured in main block'); END: /
Kodförklaring:
- Kodrad 2: Deklarerar variabeln 'sample_exception' som EXCEPTION-typ.
- Kodrad 3: Deklarerar proceduren nested_block.
- Kodrad 6: Skriver ut satsen "Inuti kapslat block".
- Kodrad 7: Skriver ut satsen "Höjer sample_exception från kapslat block."
- Kodrad 8: Höjning av undantaget med 'RAISE sample_exception'.
- Kodrad 10: Undantagshanterare för undantag sample_exception i det kapslade blocket.
- Kodrad 11: Skriver ut påståendet 'Undantag fångat i kapslat block. Höjning till huvudblocket'.
- Kodrad 12: Höjning av undantaget till huvudblocket (propagerar till huvudblocket).
- Kodrad 15: Skriver ut uttalandet "Inuti huvudblocket".
- Kodrad 16: Skriver ut satsen "Anropar kapslat block".
- Kodrad 17: Anropar nested_block-proceduren.
- Kodrad 18: undantag
- Kodrad 19: Undantagshanterare för sample_exception i huvudblocket.
- Kodrad 20: Skriver ut uttalandet "Undantag fångat i huvudblocket."
Viktiga punkter att notera i Undantag
- I funktion ska ett undantag alltid antingen returnera värde eller höja undantaget ytterligare. annan Oracle kommer att ge felet 'Funktion returnerad utan värde' vid körning.
- Transaktionskontrolluttalanden kan ges vid undantagshanteringsblock.
- SQLERRM och SQLCODE är de inbyggda funktionerna som ger undantagsmeddelandet och koden.
- Om ett undantag inte hanteras kommer som standard alla aktiva transaktioner i den sessionen att återställas.
- RAISE_APPLICATION_ERROR (- , ) kan användas istället för RAISE för att ta upp felet med användarkod och meddelande. Felkoden ska vara större än 20000 XNUMX och ha prefixet "-".
Sammanfattning
Efter detta kapitel. du bör kunna arbeta för följande aspekter av Pl SQL undantag
- Hantera undantagen
- Definiera ett undantag
- Höj undantaget
- Undantagsförökning