Poikkeuskäsittely sisään Oracle PL/SQL (esimerkkejä)

⚡ Älykäs yhteenveto

Poikkeuskäsittely Oracle PL/SQL tallentaa ajonaikaiset virheet, jotka estävät lohkon suorittamisen, jolloin moottori voi siirtää ohjauksen EXCEPTION-osioon, jossa ennalta määritetyt, käyttäjän määrittämät ja OTHERS-käsittelijät vastaavat, aiheuttavat tai levittävät virheitä turvallisesti.

  • ⚙️ Suorituksenaikaiset virheet: Poikkeus syntyy, kun PL/SQL-moottori kohtaa käskyn, jota se ei voi suorittaa, kuten luvun jakaminen nollalla.
  • 🧱 Lohkorakenne: Poikkeukset käsitellään EXCEPTION-osiossa WHEN-lauseiden avulla, ja WHEN OTHERS sijoitetaan aina viimeiseksi.
  • 📚 Ennalta määritetyt poikkeukset: Oracle nimeää yleisiä virheitä, kuten NO_DATA_FOUND ja ZERO_DIVIDE STANDARD-paketissa, jotka ovat valmiita havaitsemaan suoraan.
  • 🛠️ Käyttäjän määrittämät poikkeukset: Ohjelmoijat deklaroivat omat EXCEPTION-muuttujansa ja nostavat ne eksplisiittisesti RAISE-avainsanalla.
  • ⬆️ Eteneminen: Käsittelemätön poikkeus siirtyy ympäröivään lohkoon ja RAISE-käsky lähettää sen uudelleen pääohjelmalle.
  • 🤖 AI-apu: Tekoälykoodaustyökalut luonnostelevat POIKKEUS-lohkoja ja merkitsevät käsittelemättömät virhepolut tarkistuksen aikana.

Poikkeuskäsittely sisään Oracle PL / SQL

Mitä on poikkeuskäsittely PL/SQL:ssä?

Poikkeus tapahtuu, kun PL/SQL-moottori kohtaa käskyn, jota se ei voi suorittaa suorituksen aikana ilmenneen virheen vuoksi. Näitä virheitä ei havaita käännösaikana, ja siksi ne on käsiteltävä vasta suorituksen aikana.

Jos esimerkiksi PL/SQL-moottori vastaanottaa käskyn jakaa luku nollalla, se aiheuttaa virheen poikkeuksena. Poikkeuksen aiheuttaa vain PL/SQL-moottorin suorituksen aikana.

Poikkeus estää ohjelman suorittamisen, joten tällaisen tilanteen välttämiseksi virhe on tallennettava ja käsiteltävä erikseen. Tätä prosessia kutsutaan poikkeusten käsittelyksi, jossa ohjelmoija käsittelee suorituksen aikana mahdollisesti tapahtuvan virheen.

Poikkeuskäsittelyn syntaksi

Poikkeukset käsitellään lohkotasolla. Kun lohkossa tapahtuu poikkeus, ohjaus poistuu kyseisen lohkon suoritusosasta, ja poikkeus käsitellään sitten lohkon poikkeusten käsittelyosassa. Kun poikkeus on käsitelty, ohjaus ei voi palata saman lohkon suoritusosaan.

Alla oleva kuva näyttää, miten suoritusosa ja poikkeusten käsittelyosa sijaitsevat yhden PL/SQL-lohkon sisällä:

PL/SQL-lohkon rakenne, jossa on suoritus- ja poikkeusosio

Alla oleva syntaksi selittää, miten poikkeus havaitaan ja käsitellään.

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;

Syntaksiselitys:

  • Yllä olevassa syntaksissa poikkeusten käsittelylohko sisältää sarjan WHEN-ehtoja poikkeusten käsittelemiseksi.
  • Jokaista WHEN-ehtoa seuraa poikkeuksen nimi, jonka odotetaan syntyvän suorituksen aikana.
  • Kun poikkeus syntyy ajonaikana, PL/SQL-moottori etsii kyseistä poikkeusta poikkeusten käsittelyosasta alkaen ensimmäisestä WHEN-lauseesta ja edeten peräkkäin.
  • Jos se löytää käsittelijän poikkeukselle, se suorittaa kyseisen käsittelijäkoodin.
  • Jos mikään WHEN-lauseke ei vastaa poikkeukseen liittyvää lauseketta, PL/SQL-moottori suorittaa WHEN OTHERS -osan, jos sellainen on. Tämä käsittelijä on yhteinen kaikille poikkeuksille.
  • Käsittelijän suorituksen jälkeen ohjaus poistuu nykyisestä lohkosta.
  • Lohkolle voi suorittaa vain yhden poikkeuskäsittelijän suorituksen aikana. Suorituksen jälkeen moottori ohittaa loput käsittelijät ja poistuu nykyisestä lohkosta.

Huomautus: WHEN OTHERS tulisi aina sijoittaa sekvenssin viimeiseksi. WHEN OTHERSin jälkeen kirjoitetut käsittelijät eivät koskaan suoriteta, koska ohjaus poistuu lohkosta, kun WHEN OTHERS on suoritettu.

Poikkeustyypit

Poikkeuksia on kahdenlaisia PL / SQL.

  • Ennalta määritetyt poikkeukset
  • Käyttäjän määrittämät poikkeukset

Ennalta määritetyt poikkeukset

Oracle on ennalta määritellyt joitakin yleisiä poikkeuksia. Jokaisella ennalta määritellyllä poikkeuksella on yksilöllinen nimi ja virhenumero, ja ne kaikki on määritelty STANDARD-paketissa OracleKoodissa voit käyttää näitä valmiiksi määritettyjä poikkeusten nimiä suoraan vastaavien virheiden käsittelyyn. Monet niistä liittyvät suoraan yleisiin virheisiin. SQL virheitä, joihin törmäät päivittäin.

Alla on muutamia ennalta määriteltyjä poikkeuksia:

Poikkeus Virhe Code Poikkeuksen syy
ACCESS_INTO_NULL ORA-06530 Arvon määrittäminen alustamattoman objektin ominaisuuksille
CASE_NOT_FOUND ORA-06592 Mikään CASE-lausekkeen WHEN-lausekkeista ei täyty eikä ELSE-lauseketta ole määritetty
COLLECTION_IS_NULL ORA-06531 Keräysmetodien (paitsi EXISTS) käyttö tai kokoelman attribuuttien käyttö alustamattomassa kokoelmassa
CURSOR_ALREADY_OPEN ORA-06511 Yritetään avata a kohdistin joka on jo auki
DUP_VAL_ON_INDEX ORA-00001 Kaksoiskappaleen tallentaminen tietokannan sarakkeeseen, jota rajoittaa yksilöllinen indeksi
INVALID_CURSOR ORA-01001 Laittomat kursoritoiminnot, kuten avaamattoman kursorin sulkeminen
VÄÄRÄ NUMERO ORA-01722 Merkin muuntaminen numeroksi epäonnistui virheellisen numeromerkin vuoksi
DATAA EI LÖYTYNYT ORA-01403 SELECT-lauseke, joka sisältää INTO-lauseen, ei nouda rivejä
ROW_MISMATCH ORA-06504 Kohdistimen muuttujan tietotyyppi ei ole yhteensopiva kohdistimen todellisen paluuarvon tyypin kanssa.
SUBSCRIPT_BEYOND_COUNT ORA-06533 Viittaa kokoelmaan indeksinumerolla, joka on suurempi kuin kokoelman koko
SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 Viittaaminen kokoelmaan indeksinumerolla, joka on sallitun alueen ulkopuolella (esimerkiksi -1)
TOO_MANY_ROWS ORA-01422 SELECT-lauseke, jossa on INTO-lauseke, palauttaa useamman kuin yhden rivin
VALUE_ERROR ORA-06502 Aritmeettinen tai kokorajoitusvirhe (esimerkiksi muuttujalle size arvoa suuremman arvon määrittäminen)
ZERO_DIVIDE ORA-01476 Luvun jakaminen nollalla

Käyttäjän määrittämä poikkeus

Yllä olevien ennalta määritettyjen poikkeusten lisäksi ohjelmoija voi luoda mukautettuja poikkeuksia ja käsitellä niitä. Ne luodaan aliohjelmatasolla deklaraatio-osassa ja ne näkyvät vain kyseisen aliohjelman sisällä. Paketin määrityksessä määritelty poikkeus on julkinen poikkeus ja näkyy kaikkialla, missä pakettiin pääsee käsiksi.

Syntaksi: Aliohjelmatasolla

DECLARE
<exception_name> EXCEPTION;
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN
<Handler>
END;
  • Yllä olevassa syntaksissa muuttuja 'exception_name' on määritelty EXCEPTION-tyypiksi.
  • Sitä voidaan sitten käyttää samalla tavalla kuin ennalta määritettyä poikkeusta.

Syntaksi: Paketin spesifikaation tasolla

CREATE PACKAGE <package_name>
 IS
<exception_name> EXCEPTION;
.
.
END <package_name>;
  • Yllä olevassa syntaksissa muuttuja 'exception_name' on määritelty EXCEPTION-tyypiksi pakettispesifikaatiossa .
  • Sitä voidaan käyttää koko tietokannassa aina, kun pakettia 'paketin_nimi' voidaan kutsua.

PL/SQL-korotuspoikkeus

Kaikki ennalta määritellyt poikkeukset aktivoituvat implisiittisesti aina, kun vastaava virhe ilmenee. Käyttäjän määrittämät poikkeukset on kuitenkin aktivoitava eksplisiittisesti käyttämällä avainsanaa RAISE. RAISE-avainsanaa voidaan käyttää alla esitetyillä tavoilla.

Jos RAISE-funktiota käytetään yksinään käsittelijän sisällä, se välittää jo aiheutetun poikkeuksen päälohkoon. Sitä voidaan käyttää vain poikkeuslohkon sisällä, kuten alla on esitetty.

Alla olevassa kuvakaappauksessa näkyy, kuinka RAISE-funktiota käytetään yksinään poikkeuksen uudelleen herättämiseen sulkeutuvaan lohkoon:

Poikkeuksen levittäminen päälohkoon pelkällä RAISE-komennolla

CREATE [ PROCEDURE | FUNCTION ]
 AS
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN
             <Handler>
RAISE;
END;

Syntaksiselitys:

  • Yllä olevassa syntaksissa avainsanaa RAISE käytetään poikkeusten käsittelylohkon sisällä.
  • Aina kun ohjelma kohtaa poikkeuksen 'poikkeuksen_nimi', poikkeus käsitellään ja suoritetaan normaalisti.
  • Käsittelijän avainsana RAISE levittää sitten saman poikkeuksen pääohjelmalle.

Huomautus: Kun poikkeus tehdään päälohkoon, poikkeuksen on oltava näkyvissä myös päälohkossa; muuten Oracle antaa virheen.

Voit myös käyttää avainsanaa RAISE ja sen perässä olevaa poikkeuksen nimeä laukaistaksesi kyseisen käyttäjän määrittämän tai ennalta määritetyn poikkeuksen. Tätä lomaketta voidaan käyttää sekä suoritusosassa että poikkeusten käsittelyosassa.

Alla olevassa kuvakaappauksessa näkyy RAISE-komento ja sen perässä poikkeuksen nimi tietyn poikkeuksen aiheuttamiseksi:

Nimetyn poikkeuksen nostaminen komennolla RAISE ja sen perässä olevalla poikkeuksen nimellä

CREATE [ PROCEDURE | FUNCTION ]
AS
BEGIN
<Execution block>
RAISE <exception_name>
EXCEPTION
WHEN <exception_name> THEN
<Handler>
END;

Syntaksiselitys:

  • Yllä olevassa syntaksissa suoritusosassa käytetään avainsanaa RAISE, jota seuraa poikkeus 'poikkeuksen_nimi'.
  • Tämä aiheuttaa kyseisen poikkeuksen suorituksen aikana, ja se täytyy sitten käsitellä tai aiheuttaa edelleen.

Esimerkki 1: Tässä esimerkissä näemme:

  • Kuinka julistaa poikkeus
  • Kuinka nostaa ilmoitettu poikkeus
  • Kuinka levittää se päälohkoon

Alla oleva kuvakaappaus näyttää koko lohkon, joka määrittelee sample_exception-poikkeuksen, nostaa sen esiin sisäkkäisen lohkon sisällä ja levittää sen päälohkoon:

PL/SQL-esimerkki käyttäjän määrittämän poikkeuksen määrittämisestä ja luomisesta sisäkkäisessä lohkossa

Seuraavassa kuvakaappauksessa sama esimerkki jatkuu, jossa päälohko lopulta tallentaa levitetyn poikkeuksen:

Tuloste, joka näyttää ensin sisäkkäisessä lohkossa ja sitten päälohkossa tallennetun poikkeuksen

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;
/

Code Selitys:

  • Code rivi 2: Muuttujan 'sample_exception' määrittäminen EXCEPTION-tyypiksi.
  • Code rivi 3: Sisäkkäisen_lohkon proseduurin määrittäminen.
  • Code rivi 6: Tulostetaan lauseke ”Sisäkkäisen lohkon sisällä”.
  • Code rivi 7: Tulostetaan lauseke ”Raising sample_exception from nested block”.
  • Code rivi 8: Poikkeuksen korottaminen käyttämällä parametria 'RAISE sample_exception'.
  • Code rivi 10: Sisäkkäisen lohkon poikkeuksen sample_exception poikkeuskäsittelijä.
  • Code rivi 11: Tulostaa lauseen ”Poikkeus siepattu sisäkkäisessä lohkossa. Siirtyy päälohkoon”.
  • Code rivi 12: Poikkeuksen nostaminen päälohkoon (sen levittäminen).
  • Code rivi 15: Tulostetaan lauseke ”Päälohkon sisällä”.
  • Code rivi 16: Lausunnon "Sisäkkäistä lohkoa kutsuminen" tulostaminen.
  • Code rivi 17: Kutsutaan nested_block-proseduuria.
  • Code rivi 19: Päälohkon sample_exceptionin poikkeuskäsittelijä.
  • Code rivi 20: Tulostaa lauseen ”Poikkeus tallennettu päälohkoon”.

Tärkeitä huomioita kohdassa Poikkeus

  • Funktiossa poikkeuksen tulisi aina joko palauttaa arvo tai nostaa poikkeusta entisestään; muuten Oracle heittää suorituksen aikana virheen 'Function returned without a value'.
  • Transaktioiden hallintalausekkeet voidaan antaa poikkeusten käsittelylohkon sisällä.
  • SQLERRM ja SQLCODE ovat sisäänrakennettuja funktioita, jotka palauttavat poikkeusviestin ja poikkeuskoodin.
  • Jos poikkeusta ei käsitellä, oletusarvoisesti kaikki kyseisen istunnon aktiiviset tapahtumat peruutetaan.
  • NOSTA_SOVELLUS_VIRHE (- , ) voidaan käyttää RAISE-funktion sijaan virheen näyttämiseen mukautetulla koodilla ja viestillä. Virhekoodin on oltava välillä -20000 ja -20999.

UKK

PRAGMA EXCEPTION_INIT yhdistää käyttäjän määrittämän poikkeusnimen tiettyyn Oracle virhenumero. Sidonnan jälkeen voit tallentaa ORA-virheen nimen perusteella WHEN-lausekkeeseen WHEN OTHERS -lauseen käyttämisen ja SQLCODE-lauseen tarkistamisen sijaan.

SQLCODE palauttaa nykyisen poikkeuksen numeerisen virhekoodin, kun taas SQLERRM palauttaa sen tekstiviestin. Molempia kutsutaan poikkeusten käsittelijän sisällä, useimmiten WHEN OTHERS -lohkossa, kirjaamaan tai näyttämään, mikä meni pieleen.

Vältä WHEN OTHERS -käskyä, joka nielee kaikki virheet hiljaa. Ilman SQLCODE:n ja SQLERRM:n kirjaamista tai uudelleennostoa RAISE-käskyllä ​​se piilottaa virheet. Käytä sitä vain poikkeuksen kirjaamiseen, puhdistamiseen ja levittämiseen.

RAISE_APPLICATION_ERROR hyväksyy virhenumeron väliltä -20000 ja -20999 sekä enintään 2048 tavua pitkän viestin. Se pysäyttää suorituksen ja palauttaa mukautetun virheen kutsuvalle sovellukselle, jolloin käyttäjän määrittämä ehto näyttää alkuperäiseltä. Oracle virhe.

Ei samassa lohkossa — kun ohjaus siirtyy EXCEPTION-osioon, kyseinen lohko päättyy. Jatkaaksesi kääri riskialtis lauseke sisäiseen BEGIN…EXCEPTION…END-lohkoon; virheen käsittelyn jälkeen ulompi lohko jatkaa suorittamista.

Virhe on mikä tahansa ajonaikainen tai käännösongelma koodissa. Poikkeuksena on PL/SQL:n ajonaikainen mekanismi, joka edustaa ajonaikaista virhettä ja siirtää ohjauksen EXCEPTION-osioon, jotta ohjelma voi vastata äkillisen päättymisen sijaan.

Kyllä. Tekoälyavustajat ja koneoppimisen koodin tarkistajat luonnostelevat POIKKEUS-lohkoja, ehdottavat, mitkä ennalta määritellyt poikkeukset kannattaa napata, ja merkitsevät koodipolkuja, joista puuttuu käsittelijöitä. Kehittäjän tulisi silti vahvistaa logiikka ja virheilmoitukset ennen käyttöönottoa.

GitHub Copilot Täydentää automaattisesti WHEN-lauseet, RAISE_APPLICATION_ERROR-kutsuja ja täydellisiä EXCEPTION-lohkoja lyhyestä, tarkoitusta kuvaavasta kommentista. Se nopeuttaa rutiininomaista käsittelijän koodausta, vaikka luodut virhekoodit ja viestit vaativatkin tarkistusta oikeellisuuden varmistamiseksi.

Tiivistä tämä viesti seuraavasti: