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.

Undantagshantering i PL/SQL

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.

  1. Fördefinierade undantag
  2. 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.

PL/SQL-höjningsundantag

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.

PL/SQL-höjningsundantag

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

PL/SQL-höjningsundantag

PL/SQL-höjningsundantag

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