2009-11-19 7 views
14

Possiamo utilizzare RAISE per attivare un'eccezione. Quali situazioni particolari abbiamo bisogno di utilizzare RAISE_APPLICATION_ERROR?Oracle: qual è la situazione da utilizzare RAISE_APPLICATION_ERROR?

Grazie.

+0

Ho trovato un collegamento utile per una domanda simile. http://www.toadworld.com/platforms/oracle/b/weblog/archive/2010/07/14/raise-vs-raise-application-error.aspx –

risposta

27

Esistono due usi per RAISE_APPLICATION_ERROR. Il primo è sostituire i messaggi di eccezione generici di Oracle con i nostri messaggi più significativi. Il secondo è creare le nostre condizioni di eccezione, quando Oracle non le getterebbe.

La seguente procedura illustra entrambi gli usi. Applica una regola aziendale che i nuovi dipendenti non possono essere assunti in futuro. Sovrascrive anche due eccezioni Oracle. Uno è DUP_VAL_ON_INDEX, che viene lanciato da una chiave univoca su EMP(ENAME). L'altra è un'eccezione definita dall'utente generata quando viene violata la chiave esterna tra EMP(MGR) e EMP(EMPNO) (poiché un manager deve essere un dipendente esistente).

create or replace procedure new_emp 
    (p_name in emp.ename%type 
     , p_sal in emp.sal%type 
     , p_job in emp.job%type 
     , p_dept in emp.deptno%type 
     , p_mgr in emp.mgr%type 
     , p_hired in emp.hiredate%type := sysdate) 
is 
    invalid_manager exception; 
    PRAGMA EXCEPTION_INIT(invalid_manager, -2291); 
    dummy varchar2(1); 
begin 
    -- check hiredate is valid 
    if trunc(p_hired) > trunc(sysdate) 
    then 
     raise_application_error 
      (-20000 
      , 'NEW_EMP::hiredate cannot be in the future'); 
    end if; 

    insert into emp 
     (ename 
      , sal 
      , job 
      , deptno 
      , mgr 
      , hiredate) 
    values  
     (p_name 
      , p_sal 
      , p_job 
      , p_dept 
      , p_mgr 
      , trunc(p_hired)); 
exception 
    when dup_val_on_index then 
     raise_application_error 
      (-20001 
      , 'NEW_EMP::employee called '||p_name||' already exists' 
      , true); 
    when invalid_manager then 
     raise_application_error 
      (-20002 
      , 'NEW_EMP::'||p_mgr ||' is not a valid manager'); 

end; 
/

Come appare:

SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate+1) 
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate+1); END; 

* 
ERROR at line 1: 
ORA-20000: NEW_EMP::hiredate cannot be in the future 
ORA-06512: at "APC.NEW_EMP", line 16 
ORA-06512: at line 1 

SQL> 
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 8888, sysdate) 
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 8888, sysdate); END; 

* 
ERROR at line 1: 
ORA-20002: NEW_EMP::8888 is not a valid manager 
ORA-06512: at "APC.NEW_EMP", line 42 
ORA-06512: at line 1 


SQL> 
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate) 

PL/SQL procedure successfully completed. 

SQL> 
SQL> exec new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate) 
BEGIN new_emp ('DUGGAN', 2500, 'SALES', 10, 7782, sysdate); END; 

* 
ERROR at line 1: 
ORA-20001: NEW_EMP::employee called DUGGAN already exists 
ORA-06512: at "APC.NEW_EMP", line 37 
ORA-00001: unique constraint (APC.EMP_UK) violated 
ORA-06512: at line 1 

nota la diversa uscita dai due chiamate per raise_application_error nelle ECCEZIONI blocco. L'impostazione del terzo argomento opzionale su TRUE significa che RAISE_APPLICATION_ERROR include l'eccezione di attivazione nello stack, che può essere utile per la diagnosi.

Vi sono altre informazioni utili in the PL/SQL User's Guide.

1

se l'applicazione accetta errori sollevati da Oracle, quindi è possibile utilizzarlo. abbiamo un'applicazione, ogni volta che si verifica un errore, chiamiamo raise_application_error, l'applicazione aprirà una finestra rossa per mostrare il messaggio di errore che forniamo attraverso questo metodo.

Quando si utilizza il codice dotnet, io uso solo "raise", eccenet dotnet mechanisim acquisirà automaticamente l'errore passato da Oracle ODP e mostrato all'interno del mio codice di eccezione catch.

3

Solo per elaborare un po 'di più sulla risposta di Henry, è anche possibile utilizzare specifici codici di errore, da raise_application_error e gestirli di conseguenza sul lato client. Per esempio:

Supponete di avere una procedura di PL/SQL come questo per verificare l'esistenza di un record di posizione:

PROCEDURE chk_location_exists 
    (
     p_location_id IN location.gie_location_id%TYPE 
    ) 
    AS 
     l_cnt INTEGER := 0; 
    BEGIN 
     SELECT COUNT(*) 
     INTO l_cnt 
     FROM location 
     WHERE gie_location_id = p_location_id; 

     IF l_cnt = 0 
     THEN 
      raise_application_error(
      gc_entity_not_found, 
      'The associated location record could not be found.'); 
     END IF; 
    END; 

Il raise_application_error consente di sollevare un codice di errore specifico. Nell'intestazione del pacchetto, è possibile definire: gc_entity_not_found INTEGER := -20001;

Se avete bisogno di altri codici di errore per altri tipi di errori, è possibile definire altri codici di errore utilizzando -20.002, -20.003, ecc

Poi sul client lato, si può fare qualcosa di simile (questo esempio è per C#):

/// <summary> 
/// <para>Represents Oracle error number when entity is not found in database.</para> 
/// </summary> 
private const int OraEntityNotFoundInDB = 20001; 

e si può eseguire il codice in un blocco try/catch

try 
{ 
    // call the chk_location_exists SP 
} 
catch (Exception e) 
{ 
    if ((e is OracleException) && (((OracleException)e).Number == OraEntityNotFoundInDB)) 
    { 
     // create an EntityNotFoundException with message indicating that entity was not found in 
     // database; use the message of the OracleException, which will indicate the table corresponding 
     // to the entity which wasn't found and also the exact line in the PL/SQL code where the application 
     // error was raised 
     return new EntityNotFoundException(
      "A required entity was not found in the database: " + e.Message); 
    } 
} 
7

Si utilizza RAISE_APPLICATION_ERROR per creare un'eccezione/errore di stile Oracle specifico per il proprio codice/esigenze. Un buon utilizzo di questi aiuti consente di produrre codice più chiaro, più gestibile e più facile da eseguire il debug.

Per esempio, se ho un applicazione che si chiama una stored procedure che aggiunge un utente e l'utente esiste già, è solitamente tornare un errore del tipo:

ORA-00001: unique constraint (USERS.PK_USER_KEY) violated 

Ovviamente questo errore e messaggio associato sono non unico per il compito che stavi cercando di fare. La creazione di errori dell'applicazione Oracle personali consente di essere più chiari sull'intento dell'azione e sulla causa del problema.

raise_application_error(-20101, 'User ' || in_user || ' already exists!'); 

Ora il codice dell'applicazione può scrivere un gestore di eccezioni per elaborare questa condizione di errore specifica. Consideralo come un modo per comunicare a Oracle condizioni di errore che la tua applicazione si aspetta in una "lingua" (per mancanza di un termine migliore) che hai definito ed è più significativa per il dominio problematico della tua applicazione.

Si noti che gli errori definiti dall'utente devono essere compresi nell'intervallo tra -20000 e -20999.

Il seguente numero link fornisce molte informazioni utili su questo argomento e le eccezioni Oracle in generale.

Problemi correlati