À propos du problème de renvoi du message de capture anormale GET DIAGNOSTICS dans la procédure / fonction stockée MYSQL

Lors du traitement de SQLEXCEPTION dans le stockage MySQL, si vous utilisez GET CURRENT DIAGNOSTICS CONDITION 1 @SQL_MSG_CODE = RETURNED_SQLSTATE, @SQL_MSG_TEXT = MESSAGE_TEXT; pour lire le message qui est le premier message d'erreur affiché à chaque fois, alors comment? Que diriez-vous d'afficher les dernières informations d'erreur? Veuillez vous référer à l'exemple suivant:

 

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;

Il convient de noter que
1. L'instruction GET DIAGNOSTICS effacera également le contenu de la zone de diagnostic en cours, de sorte que l'instruction d'insertion dans le gestionnaire de conditions est supprimée du code ci-dessus et le résultat est le même.
2. Si la procédure stockée ci-dessus est modifiée comme suit, Autrement dit, placez les trois instructions de déclaration de variable dans le
gestionnaire de déclaration. Le résultat réel dépendra de la version de MySQL. S'il s'agit d'une version antérieure à MySQL-5.7.2, les modifications suivantes n'affecteront pas le contenu de la zone de diagnostic. Le résultat réel est le même que le résultat ci-dessus. S'il s'agit de MySQL-5.7.2 et des versions ultérieures, l'instruction declare variable effacera le contenu de la zone de diagnostic actuelle.

 

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;
...

Ainsi, lorsque vous avez besoin d'obtenir le contenu dans la zone de diagnostic, vous devez l'obtenir à partir de la zone de diagnostic de la pile et non de la zone de diagnostic actuelle. 

 

Je suppose que tu aimes

Origine blog.csdn.net/bj_chengrong/article/details/103297865
conseillé
Classement