Oracle contract by desing la gestione errori

41
PL/SQL Contract by Design e Gestione degli Errori

Transcript of Oracle contract by desing la gestione errori

PL/SQLContract by Design

eGestione degli Errori

Lavorare con le eccezioni

Cos'è una eccezione ?Chiamiamo eccezione un evento indesiderabile ed inaspettatoIl processo passa dall'esecuzione del blocco normale all'esecuzione del blocco delle eccezioni.Il processo chiamante viene informato del fatto che la normale esecuzione del programma si è interrotta a causa di un evento inaspettato.Se possibile, il modulo chiamato indica al chiamante l'evento inaspettato che si è verificato

Classificazione delle eccezioniPreviste,recuperabili, falsi allarmi.

Bisogna preservare il normale flusso del programma (possono essere gestite con sub-block)

Previste ma irrecuperabili.Violazione degli obblighi contrattuali da parte del

modulo chiamante. Sono segnalate al chiamante per la loro gestione.

Impreviste ma gestibiliLoggate in una tabella di errori per successiva analisi

Impreviste ingestibiliLoggate in una tabella di errori

Evitare le eccezioni impreviste

Come evitare le eccezioni impreviste ?L'analisi dovrebbe prevedere:

Lo scenario normale

Uno o più scenari alternativi

Gli scenari di errore

(si veda l'esempio di modulo per l'analisi dei casi d'uso)

Ordinare bene i processi del modulo

Ecco come ordinare i processi nel modulo :Controllo formale dei parametri di ingresso

I parametri rispettano i datatype ed il formato previsto dal modulo chiamato ?

Controllo semantico dei parametri di ingressoI parametri hanno il corretto significato per il modulo ? (ad

esempio il codice impiegato identifica davvero un dipendente ?)

Controllo corretta esecuzione degli algoritmi del modulo

Scrivere il codice cercando di prevenire gli errori

Ordinare bene i processi del modulo

Controllo formale dei parametri di output I parametri rispettano i datatype ed il formato previsto

dal modulo chiamante ?Controllo semantico dei parametri di output

I parametri hanno il corretto significato per il modulo chiamante ?

Controllo che gli errori eventualmente restituiti al modulo chiamato abbiamo un significato chiaro

Chi riceve l'errore deve capire quale tipo di errore si è verificato ed eventualmente ricevere indicazioni su come trattarlo

Ecco alcuni esempi praticiProcesso di ETL

Come gestire gli errori in PL/SQL

I tipi di errore Oracle

Nel mondo pl/sql ci sono tre grandi categorie di errori:

Quelli interni definiti dal server oracle

Predefiniti

Definiti dall'utente

I tipi di errore Oracle

Gli errori interni:

Sono quelli generati da un processo interno del database oracle.

Queste eccezioni hanno sempre un codice ma non hanno un nome a meno che questo nome sia assegnato dal motore pl/sql o dall'applicativo. Un esempio di un'eccezione definita internamente è ORA-00060 (deadlock rilevati durante l'attesa della risorsa).

I tipi di errore Oracle

Gli errori predefiniti: Un'eccezione predefinita è un'eccezione definita

internamente da PL / SQL a cui viene assegnato un nome . La maggior parte delle eccezioni predefinite sono definite nel package standard (un package fornito da Oracle che definisce molti elementi di programmazione comuni del linguaggio PL/SQL) .

Un esempio è ORA-00001, a cui viene assegnato il nome DUP_VAL_ON_INDEX in PL/SQL e viene generata quando viene violato il vincolo di unicità creato da un indice “unique” oppure dalla chiave primaria di una tabella.

I tipi di errore Oracle

Gli errori definiti dall'applicativo: Le eccezioni definite dall'applicativo sono quelle inserite

nella sezione “declare” di un blocco PL/Sql.

Oracle mette a disposizione due strumenti per sollevare eccezioni: L'istruzione raise Procedura “raise_application_error”

Le A.P.I. di Oracle per segnalare gli erroriDescrizione Come recuperare l'informazioneCodice dell'errore Variabile sqlcode Questo codice è utile quando

è necessario cercare informazioni generiche su cosa potrebbe aver causato il problema.

Messaggio d'errore Variabile sqlerrm (massimo 512 byte) Oppure

DBMS_UTILITY.FORMAT_ERROR_STACK

Questo testo spesso contiene indicazioni

specifiche quali il nome della constraint o della

colonna che ha generato il problema

Individuare la linea di codice dove è stata sollevata l'eccezione

DBMS_UTILITY.FORMAT_ERROR_BACKTRACE

Questo è di grande aiuto nel rintracciare la

causa degli errori.

Call stack: Questo risponde alla domanda come ho fatto ad arrivare qui ?

DBMS_UTILITY.FORMAT_CALL_STACK

Indica le chiamate fatte per arrivare al punto

in cui si è verificato l'errore

Contract by design ed errori pl/sql

Disegnare un applicazione compliant “contract by design”

Contract Specification Assert

Disegnare un applicazione compliant “contract by design”

Il controllo dei parametri di inputIl Controllo formale dei parametri eseguito dalle assert

I parametri che non rispettano i datatype previsti generano errori che non possono essere gestiti dal modulo chiamato

Il controllo del processo viene restituito al modulo chiamante con un messaggio di errore che indica quale parametro non rispetta il contratto

Si suggerisce al modulo chiamante come chiamare correttamente il modulo

Sollevare le eccezioni con le assertpackage dbcisAssertFail exception;c_AssertFail constant integer := -20999;pragma exception_init (AssertFail, -20999);procedure assert (p_check in boolean,p_msg in varchar2 := null);end dbc;procedure assert (p_check in boolean,p_msg in varchar2 := null)isbeginif not nvl(p_check,false) -- fail on null inputthenraise_application_error( c_AssertFail, 'Assertion Fail'||': '||substr( nvl(p_msg, 'No Message'), 1, 200));end if;end assert;

Trattandosi di eccezioni che devono essere sollevate dall'applicativo , possiamo utilizzare la procedure “raise_application_error” messaci a disposizione da pl/sql

Il controllo dei parametri di inputCosa controllare

Controllo che i parametri rispettino i datatype previsti ( porre particolare attenzione alle conversioni implicite stringhe => numeri, numeri => stringhe, stringhe => date)

Controllo che il formato dei parametri rispetti quello previsto ( porre particolare attenzione alle stringhe che devono essere trasformate in date utilizzare sempre l'interprete FX => Format eXact e non il formato di default Fill Mode)

Il controllo dei parametri di inputControllo formale delle date con il formato Format eXact

Il controllo dei parametri di inputControllo formale delle date con il formato Format eXact

Il controllo dei parametri di inputConversioni tra stringhe e numeri controllo formale che una stringa contenga solo numeri

Il controllo dei parametri di input

Le “business rules” del modulo devono determinare il significato semantico dei parametri di ingresso

Il “contratto” stipulato con i moduli chiamanti deve spiegare il significato semantico dei parametri di ingresso

Le “business rules” del modulo determinano quali errori sono “fatali” ed impediscono l'elaborazione del modulo

I messaggi di errore indicano al modulo chiamante quale parametro ha generato l'errore e l'errore generato

Il controllo dei parametri di input

Esempi di controllo <<semantico>> dei parametri di ingresso

Il dato deve avere il significato corretto per il modulo chiamato.

Il codice cliente inputato corrisponde davvero ad un cliente ?

La data inserita nel parametro rientra nella forchetta data min e data max previsti dal modulo?

L'ordine inserito dal cliente supera il fido massimo concesso e non può essere processato?

Il codice dell'articolo corrisponde ad un nostro articolo?

Controllo esecuzione algoritmoEsempio di etl (extract,trasform,load)

Il controllo esecuzione algoritmoLe “business rules” definiscono gli scenari di errore.

Errori previsti, recuperabili e falsi allarmi

Bisogna preservare il normale flusso del programma mediante l'uso dei sotto-blocchi

Previsti ma irrecuperabili (sono previste apposite eccezioni definite dall'utente )

Il messaggio di errore avvisa il modulo chiamante e l'errore viene scritto nei log per successive analisi

Imprevisti e quindi ingestibili (sono intercettate dal gestore di eccezioni when others)

Il messaggio di errore avvisa il modulo chiamante e l'errore viene scritto nei log per successive analisi

Annidamento - flusso programma exceptions

Begin

BeginExceptionEnd;

BeginEnd;

BeginExceptionEnd;

ExceptionEnd;

Eccezione out

Eccezione gestita dal blocco

Fine esecuzione normale

Eccezione gestita dal blocco

Eccezione gestita dal blocco

Usare l'annidamento per far proseguire il normale flusso del programma

Usare l'istruzione raise o raise_application_error per interrompere il normale flusso del programma

Annidamento - exceptions

NON interrompe

Annidamento - exceptions

interrompe il flusso

Controllo esecuzione algoritmoIl controllo delle righe estratte

Controllare il numero di righe estratte dal cursore utilizzando l'attributo del cursore sql%rowcount oppure nel caso di “bulk collect” l'attributo “count” della collection.

Controllo esecuzione algoritmoIl controllo delle righe estratte (bulk collect)

Gestione degli errori

Quando un'eccezione Oracle può essere anticipata in una sezione di codice,

e l'eccezione può essere gestita in sicurezza,

bisogna racchiudere il codice in un sotto-blocco e gestire l'eccezione (solo quella eccezione)

Blocco Esterno

Blocco internocon eccezionegestita

GestireLe eccezioniCon sub-blocchi

Il controllo esecuzione algoritmoLe cattive abitudini :

Solleva l'eccezione ed ignorala . La caccia all'errore diventerà difficile e ti impgnerà lungamente

Maschera tutti gli errori. Il modulo chiamante è convinto della corretta esecuzione dell'algoritmo

Maschera tutti gli errori. Le post condizioni sono violate ed inducono in errore il modulo chiamato

Il modulo non è sincero mente mascherando gli errori

Usare correttamente il bloccoexception

Non mascherare l'errore con un blocco exception che non fa nulla!

L'eccezione deve essere almeno sempre loggata.

Caccia al misterioso errore

Usare correttamente il bloccoexception

Attenzione alle modifiche di data-type che possono generare errori difficili da individuare se non correttamente gestiti nel blocco exception

Caccia al misterioso errore

Attenzione alle chiamate di procedure a cascata

L'ultima procedura chiamata B sovrascrive la variabile err_msg settandola a null

Una corretta gestione degli errori in PL/SQL

Perchè gestire bene gli errori ? Maggiore precisione nell'individuare dove è stata sollevata l'eccezione .

Minore necessità di perdere tempo nel fare debug step by step .

Minore necessità di ricicli

Maggiore possibilità di prevenire proto-attivamente bugs .

Creare una tabella di log erroricreate table LOG_ERRORS(

t_error TIMESTAMP(6), d_error DATE, c_package VARCHAR2(30), c_module VARCHAR2(30), n_sqlcode NUMBER, c_sqlerrm VARCHAR2(1000), c_note VARCHAR2(4000), callstack VARCHAR2(4000), errorstack VARCHAR2(4000), backtrace VARCHAR2(4000), db_instance VARCHAR2(100), host VARCHAR2(100), terminal VARCHAR2(100), ip_adress VARCHAR2(100), session_user VARCHAR2(100));

Timestamp di quando si è verificato l'erroreData errorePackage dove è stato sollevato l'erroreProcedura/funzione sollevato l'erroreCodice dell'erroreMessaggio dell'erroreCampo nel quale inserire i parametri chiamataInserisce stack delle chiamateMessaggio di errore originaleRicostruzione delle chiamate fino all'erroreIstanza del db dove si è verificato l'errorehostTerminale dal quale è stato eseguita la chiamataIndirizzo IPNome della sessione

la procedura per il log errori