Formation PUB200 : MySQL, 2018 Les gestionnaires (handlers)

17.4 Retrouver les informations sur l'erreur interceptée par le gestionnaire (GET DIAGNOSTICS)


Dans vos procédures et fonctions stockées, vous devriez toujours prévoir tous les cas d'erreur possibles. Comme il serait fastidieux de créer un gestionnaire pour chacune des exceptions imaginable, on utilisera plutôt un gestionnaire pour l'exception SQLEXCEPTION.

Lorsqu'une erreur inattendue est détectée par SQLEXCEPTION, on voudra savoir qu'est-ce qui a causé le problème exactement­.

Avec un gestionnaire sur SQLEXCEPTION qui vous donne de l'information sur l'erreur rencontrée, le débogage de vos procédures et fonctions stockées sera plus facile.

L'instruction GET DIAGNOSTICS, placée à l'intérieur d'un DECLARE CONTINUE HANDLER, permet de retrouver de l'information sur l'exception qui a été levée, par exemple le code de l'erreur et son message. Ces informations seront stockées dans des variables et pourront être utilisées plus tard.

GET DIAGNOSTICS utilise la syntaxe suivante :

Syntaxe MySQL

GET DIAGNOSTICS CONDITION numero_condition

    variable_1 = information_1,

    variable_2 = information_2;

Comme numéro de condition, nous utiliserons presque toujours la valeur 1. Un autre numéro pourrait être utilisé dans le cas où l'instruction GET DIAGNOSTICS ou RESIGNAL aurait elle-même levé une exception, tel que démontré ici : http://dev.mysql.com/doc/refman/5.7/en/diagnostics-area.html#diagnostics-area-populating. Comme il s'agit d'un cas très particulier, nous nous en tiendrons au numéro 1.

La liste des informations pouvant être retrouvées par GET DIAGNOSTICS comprend :

  • CLASS_ORIGIN
  • SUBCLASS_ORIGIN
  • RETURNED_SQLSTATE
  • MESSAGE_TEXT
  • MYSQL_ERRNO
  • CONSTRAINT_CATALOG
  • CONSTRAINT_SCHEMA
  • CONSTRAINT_NAME
  • CATALOG_NAME
  • SCHEMA_NAME
  • TABLE_NAME
  • COLUMN_NAME
  • CURSOR_NAME

Pour une description de ces informations, consultez cette page : http://dev.mysql.com/doc/refman/5.7/en/diagnostics-area.html#diagnostics-area-information-items.

Ex :

MySQL

GET DIAGNOSTICS CONDITION 1

    mysql_errno = MYSQL_ERRNO,

    message_text = MESSAGE_TEXT;

Voici comment imbriquer un GET DIAGNOSTICS à l'intérieur du gestionnaire pour l'exception SQLEXCEPTION :

MySQL

CREATE PROCEDURE copier_table_mecaniciens(OUT code_erreur INT)

BEGIN

    -- Copie la table mecaniciens dans copiemecaniciens  

    -- Programmé par : Annie Gagnon

    -- Le : 2 novembre 2016

    -- Paramètres : OUT code de l'erreur rencontrée 

    -- Valeurs possibles :

    --     0            : copie effectuée avec succès

    --     -1           : copie non effectuée car la table copiemecaniciens existait déjà

    --     -2           : copie non effectuée car aucune donnée à copier

    --     Autre nombre : une erreur est survenue. La valeur de retour constitue le code MySQL de l'erreur.

    -- Historique des modifications

    -- Par : Annie Gagnon

    -- Le : 8 novembre 2016

    -- Modifications : En cas d'erreur autre que table_existe_deja,

    --                 enregistre le code et le message d'erreur dans le journal des erreurs.

    --                 La valeur de retour sera -1 (et non plus 1050) quand la table existait déjà.

    --                 Pour toute autre erreur, c'est le code d'erreur MySQL qui sera la valeur de retour.

 

    -- déclaration de variables locales

    DECLARE nombre INT;

 

    DECLARE mysql_errno INT;

    DECLARE message_text TEXT;

 

    -- déclaration de conditions

    DECLARE table_existe_deja CONDITION FOR 1050;

 

    -- déclaration de gestionnaires

    DECLARE CONTINUE HANDLER FOR table_existe_deja SET code_erreur=-1;

    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION

    BEGIN

        -- retrouve les informations sur l'erreur

        GET DIAGNOSTICS CONDITION 1

            mysql_errno = MYSQL_ERRNO,

            message_text = MESSAGE_TEXT;

 

        -- enregistre les informations sur l'erreur dans le journal des erreurs

        INSERT INTO journalerreurs (message) VALUES (CONCAT('Erreur inattendue :', mysql_errno, ': ', message_text));

 

        -- initialise la valeur de retour

        SET code_erreur = mysql_errno;

    END;

 

    -- traitement

    SET code_erreur=0;

 

    SELECT COUNT(*) INTO nombre FROM mecaniciens;

 

    IF nombre > 0 THEN

        CREATE TABLE copiemecaniciens AS (SELECT * FROM mecaniciens);

        IF code_erreur = -1 THEN

            -- pour tous les autres codes d'erreur, le gestionnaire de SQLEXCEPTION a déjà fait l'insertion

            INSERT INTO journalerreurs (message) VALUES ('La table copiemecaniciens existait déjà. La copie n''a pas eu lieu.');

        END IF;

    ELSE

        -- le programme PHP saura que la valeur -2 signifie que la table n'a pas été créée pcq rien à copier dedans

        SET code_erreur=-2;

    END IF;

END$$

Pour plus d'information

« GET DIAGNOSTICS Syntax ». MySQL. http://dev.mysql.com/doc/refman/5.7/en/get-diagnostics.html

« GET DIAGNOSTICS ». SQL And Its Sequels. http://ocelot.ca/blog/blog/2014/11/16/get-diagnostics/

« Using GET DIAGNOSTICS in MySQL 5.6 ». Guy Harrison's web bits. http://guyharrison.squarespace.com/blog/2013/7/5/using-get-diagnostics-in-mysql-56.html

▼Publicité

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre