2011-10-14 49 views
10

Creo que no hay nada actualmente disponible en MySQL que permita el acceso al SQLSTATE de la última instrucción ejecutada dentro de un procedimiento almacenado de MySQL. Esto significa que cuando se genera una SQLException genérica dentro de un procedimiento almacenado, es difícil/imposible derivar la naturaleza exacta del error.MySQL Stored Procedure Error Handling

¿Alguien tiene una solución para derivar el SQLSTATE de un error en un procedimiento almacenado de MySQL que no implica declarar un controlador para cada SQLSTATE posible?

Por ejemplo - Imagino que estoy tratando de devolver un error_status que va más allá de la "excepción de SQL sucedido en alguna parte de este bloque BEGIN....END" genérica en lo siguiente:

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$$ 

Algún consejo?

PS Estoy corriendo MySQL 5.1.49

Respuesta

8

Creo que no hay nada actualmente disponible en MySQL que permite el acceso a la SQLSTATE de la última sentencia ejecutada dentro de un procedimiento almacenado de MySQL. Esto significa que ... es difícil/imposible derivar la naturaleza exacta del error.

Afortunadamente eso no es verdad.

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

Mostrará el último error o advertencia.

Con el fin de prevenir la lista de todos y cada uno de error, que puede manejar una clase de SQL-errores de este modo:

SQLWARNING es la abreviatura de la clase de los valores de SQLSTATE que comienzan con '01'.

NO ENCONTRADO es la abreviatura de la clase de valores de SQLSTATE que comienzan con '02'. Esto solo es relevante dentro del contexto de los cursores y se usa para controlar lo que sucede cuando un cursor llega al final de un conjunto de datos. Si no hay más filas disponibles, se produce una condición Sin datos con el valor SQLSTATE 02000. Para detectar esta condición, puede configurar un controlador para ello (o para una condición NO ENCONTRADA). Un ejemplo se muestra en la Sección 12.7.5, "Cursores". Esta condición también ocurre para SELECT ... INTO var_list declaraciones que no recuperan filas.

SQLEXCEPTION es una abreviación para la clase de valores SQLSTATE que no comienzan con '00', '01' o '02'.

Así que para manejar una excepción, es necesario única hacer:

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

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

+1

Gracias Johan. Los 'SHOW ERRORS' y 'SHOW WARNINGS' me mostrarán el SQLSTATE del último error o advertencia si se ejecuta de forma aislada. Sin embargo, ¿cómo puedo acceder a eso 'dentro de un procedimiento almacenado MySQL'? Es decir, ¿cómo puedo devolver la salida de 'SHOW ERRORS' o 'SHOW WARNINGS' en una variable de salida de procedimiento como se describe en mi pregunta original? –

0

que estoy haciendo la siguiente solución: usar una SELECCIONAR para provocar un error.Por ejemplo:

SELECT RAISE_ERROR_unable_to_update_basket; 

Esto dará como resultado el siguiente mensaje de error (ejemplo):

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

estoy envolviendo mis llamada a un procedimiento almacenado en un try {...} catch {.. .} y ahora puede manejar este error. Esto, por supuesto, solo funcionará para provocar mensajes de error personalizados desde el interior de su procedimiento almacenado y no manejará ningún SQL o error de base de datos que pueda ocurrir (debido a la entrada de clave duplicada). En este último caso, es posible que pueda solucionar esto utilizando la solución de Johan.

+0

gracias harald. Aunque en esta instancia específica estoy tratando de manejar errores SQL o de base de datos. –

Cuestiones relacionadas