Acerca del problema de devolver el mensaje de captura anormal GET DIAGNOSTICS en el procedimiento / función almacenada de MYSQL

Al procesar SQLEXCEPTION en el almacenamiento MySQL, si usa GET CURRENT DIAGNOSTICS CONDITION 1 @SQL_MSG_CODE = RETURNED_SQLSTATE, @SQL_MSG_TEXT = MESSAGE_TEXT; para leer el mensaje que es el primer mensaje de error que se muestra cada vez, ¿cómo? ¿Qué tal mostrar la información de error más reciente? Consulte el siguiente ejemplo:

 

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 TEXT NOT NULL);
DROP PROCEDURE IF EXISTS p;
delimiter //
CREATE PROCEDURE p ()
BEGIN
  -- Declare variables to hold diagnostics area information
  DECLARE errcount INT;
  DECLARE errno INT;
  DECLARE msg TEXT;
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    -- Here the current DA is nonempty because no prior statements
    -- executing within the handler have cleared it
    GET CURRENT DIAGNOSTICS CONDITION 1
      errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
    SELECT 'current DA before mapped insert' AS op, errno, msg;
    GET STACKED DIAGNOSTICS CONDITION 1
      errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
    SELECT 'stacked DA before mapped insert' AS op, errno, msg;

    -- Map attempted NULL insert to empty string insert
    INSERT INTO t1 (c1) VALUES('');

    -- Here the current DA should be empty (if the INSERT succeeded),
    -- so check whether there are conditions before attempting to
    -- obtain condition information
    GET CURRENT DIAGNOSTICS errcount = NUMBER;
    IF errcount = 0
    THEN
      SELECT 'mapped insert succeeded, current DA is empty' AS op;
    ELSE
      GET CURRENT DIAGNOSTICS CONDITION 1
        errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
      SELECT 'current DA after mapped insert' AS op, errno, msg;
    END IF ;
    GET STACKED DIAGNOSTICS CONDITION 1
      errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
    SELECT 'stacked DA after mapped insert' AS op, errno, msg;
  END;
  INSERT INTO t1 (c1) VALUES('string 1');
  INSERT INTO t1 (c1) VALUES(NULL);
END;
//
delimiter ;
CALL p();
SELECT * FROM t1;

Debe tenerse en cuenta que
1. La instrucción GET DIAGNOSTICS también borrará el contenido del área de diagnóstico actual, por lo que la instrucción de inserción en el controlador de condiciones se elimina del código anterior y el resultado es el mismo.
2. Si el procedimiento almacenado anterior se modifica de la siguiente manera, Es decir, ponga las tres declaraciones de variable declare en el
manejador de declare. El resultado real dependerá de la versión de MySQL. Si es una versión anterior a MySQL-5.7.2, las siguientes modificaciones no afectarán el contenido en el área de diagnóstico. El resultado real es el mismo que el resultado anterior.Si está en MySQL-5.7.2 y versiones posteriores, la declaración de variable declare borrará el contenido en el área de diagnóstico actual.

 

CREATE PROCEDURE p ()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- Declare variables to hold diagnostics area information
DECLARE errcount INT;
DECLARE errno INT;
DECLARE msg TEXT;
GET CURRENT DIAGNOSTICS CONDITION 1
errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
SELECT 'current DA before mapped insert' AS op, errno, msg;

GET STACKED DIAGNOSTICS CONDITION 1
errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
SELECT 'stacked DA before mapped insert' AS op, errno, msg;
...

Entonces, cuando necesite obtener el contenido en el área de diagnóstico, debe obtenerlo del área de diagnóstico de la pila, no del área de diagnóstico actual. 

 

Supongo que te gusta

Origin blog.csdn.net/bj_chengrong/article/details/103297865
Recomendado
Clasificación