2010-10-15 4 views
15

Se l'istruzione SELECT INTO non restituisce almeno una riga, viene generato ORA-01403.Perché no_data_found ORA-01403 è un'eccezione in Oracle?

Per ogni altro DBMS, so che questo è normale su un SELECT. Solo Oracle considera SELECT INTO in questo modo.

CREATE OR REPLACE PROCEDURE no_data_proc IS 
    dummy dual.dummy%TYPE; 
BEGIN 
    BEGIN 
    SELECT dummy 
     INTO dummy 
     FROM dual 
     WHERE dummy = 'Y'; 
    EXCEPTION 
    WHEN no_data_found THEN 
     dbms_output.put_line('Why is this needed?'); 
    END; 
END no_data_proc; 

Perché?

Secondo me non hai davvero bisogno di questa eccezione. È troppo sovraccarico. A volte è utile ma devi scrivere un intero BEGIN, EXCEPTION, WHEN, END Block.

Ci sono dei motivi essenziali che non vedo?

+5

Non dimenticare di prendere TOO_MANY_ROWS quando la selezione restituisce più di una riga. – Rene

risposta

18

Il blocco eccezione non è necessario , si potrebbe utilizzare o meno, a seconda del contesto.

Qui si sta attivamente ignorando l'eccezione (la procedura per ritornare con successo), ma la maggior parte del tempo se si sta facendo un SELECT INTO si vuole che riuscire se non restituisce una riga, prendere in considerazione:

PROCEDURE update_employee_salary (p_empno) IS 
    l_salary NUMBER; 
BEGIN 
    SELECT sal INTO l_salary FROM emp WHERE empno = p_empno FOR UPDATE; 
    /* do something with emp data */ 
END; 

qui voglio la mia funzione di fallire se viene chiamato con un empno che non esiste nella tabella EMP. Potrei prendere l'eccezione per sollevare un messaggio di errore significativo (con raise_application_error) ma la maggior parte delle volte sono felice con ORA-01403.

In generale, le uniche eccezioni che dovresti rilevare sono le eccezioni previste (ad esempio, questo non dovrebbe essere lo standard per catturare tutto ORA-01403 o tutte le eccezioni).

+0

SELECT INTO FOR UPDATE è stato un buon esempio. Thx –

2

Perché si sta facendo SELECT INTO che richiede esattamente una riga (più righe sarebbe anche un errore).

Se è possibile avere una o nessuna riga, è possibile utilizzare un cursore.

Non è compito del database decidere che una riga mancante non è un errore e impostare il valore su null.

6

Si può provare a utilizzare MIN per evitare l'uso della clausola EXCEPTION.

SELECT MIN(dummy) 
    INTO dummy 
    FROM dual 
    WHERE dummy = 'Y'; 

quindi variabile dummy sarà NULL

+0

Sì, è quello che faccio anch'io. – Thilo

+0

Cosa succede se hai troppe righe? Quindi dovresti selezionare la riga minima che potrebbe essere sbagliata. –

+1

@ user411718, Se prevedi di avere più righe, perché allora prova a memorizzarlo in variabile? Io uso MIN solo per i casi in cui posso ottenere una o nessuna riga, per evitare l'uso di ECCEZIONE. E quello di cui ho bisogno: solo un valore o NULL. –

11

Ma dobbiamo ancora rispondere alla domanda "perché viene generata un'eccezione nel caso in cui un SELECT non abbia dati da recuperare".

Credo che questo sia fatto perché è una situazione comune che potrebbe altrimenti essere trascurata. La scrittura di codice come se si aspetta sempre di trovare i dati è una cosa comune da fare, e se dovevamo mettere in controlli di errore come

SELECT <something...> 
IF SQLCODE = 100 THEN -- No data found 
    <no-data handler> 
END IF 

è probabile IMHO che il controllo per SQLCODE = 100 sarebbe saltato frequentemente. Avere un'eccezione ha provocato il rams sul naso che A) una condizione importante (nessun dato trovato) si è verificato, e B) NESSUNA INDENNITA È STATA FATTA PER QUESTO.L'IMO che ha il motore PL/SQL a sollevare un'eccezione è meglio che avere il programma continuare allegramente sulla sua strada, supponendo che i dati siano stati recuperati quando in realtà non lo erano, il che può portare a tutti i tipi di problemi più che felici.

Condividi e divertiti.

+0

+1 eccellente risposta. –

1

Perché non è chiaro cosa dovrebbe fare il motore PL/SQL - dovrebbe uscire dal blocco? Dovrebbe premere con NULL nella variabile? Cosa succede se nel blocco successivo si tenta di inserirlo in una colonna NOT NULL, come deve segnalare la posizione dell'errore? Farlo un'eccezione ti costringe ad essere esplicito al riguardo.

1

È inoltre possibile utilizzare le funzioni sql MAX o MIN. Se non viene restituita alcuna riga, queste funzioni restituiranno un valore NULL.

Per esempio: Selezionare MAX (column1) Into variabile Dalla Tabella Dove Colonna1 = 'valore';

La funzione MAX restituirà il valore Massimo o se non viene restituita alcuna riga, restituirà NULL.