Gestione degli errori di stored procedure MySQL

Credo che non ci sia nulla attualmente disponibile in MySQL che permetta l’accesso a SQLSTATE dell’ultima istruzione eseguita all’interno di una stored procedure MySQL. Ciò significa che quando viene SQLException una SQLException generica all’interno di una stored procedure è difficile / imansible ricavare la natura esatta dell’errore.

Qualcuno ha una soluzione alternativa per derivare lo SQLSTATE di un errore in una stored procedure MySQL che non prevede la dichiarazione di un gestore per ogni ansible SQLSTATE?

Ad esempio: immagina che sto cercando di restituire un errore_stato che vada oltre il generico “SQLException accaduto da qualche parte in questo BEGIN....END blocco BEGIN....END ” nel seguente:

 DELIMITER $$ CREATE PROCEDURE `myProcedure`(OUT o_error_status varchar(50)) MY_BLOCK: BEGIN DECLARE EXIT handler for 1062 set o_error_status := "Duplicate entry in table"; DECLARE EXIT handler for 1048 set o_error_status := "Trying to populate a non-null column with null value"; -- declare handlers ad nauseum here.... DECLARE EXIT handler for sqlexception set o_error_status:= "Generic SQLException. You'll just have to figure out the SQLSTATE yourself...." ; -- Procedure logic that might error to follow here... END MY_BLOCK$$ 

Qualche consiglio?

PS Sto eseguendo MySQL 5.1.49

GET DIAGNOSTICS è disponibile in 5.6.4

Vedi http://dev.mysql.com/doc/refman/5.6/en/get-diagnostics.html

Credo che non ci sia nulla attualmente disponibile in MySQL che permetta l’accesso a SQLSTATE dell’ultima istruzione eseguita all’interno di una stored procedure MySQL. Ciò significa che … è difficile / imansible ricavare la natura esatta dell’errore.

Fortunatamente non è vero.

 SHOW ERRORS LIMIT 1 -- for SQL-state > 2 SHOW WARNINGS LIMIT 1 -- for SQL-state 1,2 

Mostrerà l’ultimo errore o avviso.

Per evitare di elencare ogni singolo errore, puoi gestire una class di errori SQL in questo modo:

SQLWARNING è abbreviazione per la class di valori SQLSTATE che iniziano con ’01’.

NOT FOUND è una abbreviazione per la class di valori SQLSTATE che inizia con “02”. Questo è rilevante solo nel contesto dei cursori e viene usato per controllare cosa succede quando un cursore raggiunge la fine di un set di dati. Se non sono disponibili più righe, si verifica una condizione di Nessun dato con il valore SQLSTATE 02000. Per rilevare questa condizione, è ansible impostare un gestore per esso (o per una condizione NON TROVATA). Un esempio è mostrato nella Sezione 12.7.5, “Cursori”. Questa condizione si verifica anche per SELECT … INTO istruzioni var_list che non recuperano righe.

SQLEXCEPTION è una scorciatoia per la class di valori SQLSTATE che non iniziano con ’00’, ’01’ o ’02’.

Quindi per gestire un’eccezione, devi solo fare:

 DECLARE EXIT HANDLER FOR SQLSTATE SQLEXCEPTION .....; 

link:
http://dev.mysql.com/doc/refman/5.5/en/signal.html
http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html

Sto facendo la seguente soluzione: usare un SELECT per provocare un errore. Per esempio:

 SELECT RAISE_ERROR_unable_to_update_basket; 

Ciò comporterà il seguente messaggio di errore (esempio):

 ERROR 1054 (42S22): Unknown column 'RAISE_ERROR_unable_to_update_basket' in 'field list' 

Sto tagliando la mia chiamata a una stored procedure in una prova {…} catch {…} e ora posso gestire questo errore. Questo naturalmente funzionerà solo per provocare messaggi di errore personalizzati dall’interno della procedura memorizzata e non gestirà alcun errore SQL o database, che potrebbe verificarsi (a causa della voce della chiave duplicata). In quest’ultimo caso, potresti essere in grado di risolvere il problema utilizzando la soluzione di Johan.