Comment déboguer les procédures stockées MySQL?


125

Mon processus actuel de débogage des procédures stockées est très simple. Je crée une table appelée "debug" où j'insère des valeurs de variable à partir de la procédure stockée lors de son exécution. Cela me permet de voir la valeur de n'importe quelle variable à un moment donné du script, mais y a-t-il une meilleure façon de déboguer les procédures stockées MySQL?


2
Existe-t-il des options d'interface graphique pour les utilisateurs non Windows? Avoir à exécuter une copie de Windows juste pour déboguer des procédures stockées est un peu un saut. Et la plupart des options d'insertion de table échouent si vous êtes dans une transaction que vous êtes sur le point d'annuler.
Code Abominator

Réponses:


44

Je fais quelque chose de très similaire à toi.

J'inclus généralement un paramètre DEBUG qui est par défaut false et que je peux définir sur true au moment de l'exécution. Enveloppez ensuite les instructions de débogage dans un bloc "If DEBUG".

J'utilise également une table de journalisation avec plusieurs de mes travaux afin de pouvoir revoir les processus et le calendrier. Mon code de débogage y est également envoyé. J'inclus le nom du paramètre appelant, une brève description, le nombre de lignes affectées (le cas échéant), un champ de commentaires et un horodatage.

Les bons outils de débogage sont l'un des tristes échecs de toutes les plates-formes SQL.


3
Toutes les plates-formes @Bob Probst, les outils de débogage de sybase ne sont pas assez décents avec le débogage de point d'arrêt pour les procédures de déclenchement et stockées
Anup

69

La debug_msgprocédure suivante peut être appelée pour simplement afficher un message de débogage sur la console:

DELIMITER $$

DROP PROCEDURE IF EXISTS `debug_msg`$$
DROP PROCEDURE IF EXISTS `test_procedure`$$

CREATE PROCEDURE debug_msg(enabled INTEGER, msg VARCHAR(255))
BEGIN
  IF enabled THEN
    select concat('** ', msg) AS '** DEBUG:';
  END IF;
END $$

CREATE PROCEDURE test_procedure(arg1 INTEGER, arg2 INTEGER)
BEGIN
  SET @enabled = TRUE;

  call debug_msg(@enabled, 'my first debug message');
  call debug_msg(@enabled, (select concat_ws('','arg1:', arg1)));
  call debug_msg(TRUE, 'This message always shows up');
  call debug_msg(FALSE, 'This message will never show up');
END $$

DELIMITER ;

Ensuite, lancez le test comme ceci:

CALL test_procedure(1,2)

Cela entraînera la sortie suivante:

** DEBUG:
** my first debug message
** DEBUG:
** arg1:1
** DEBUG:
** This message always shows up

8
Cela ne semble pas fonctionner pour FUNCTIONS et je ne sais pas pourquoi. Il donne toujours "Code d'erreur: 1415. Impossible de renvoyer un jeu de résultats à partir d'une fonction". Y a-t-il un recours?
Patrick M

1
Les fonctions @PatrickM ne peuvent pas renvoyer de lignes ("result") tant que cette procédure de débogage s'appuie sur elle (les messages de débogage sont des ensembles de résultats renvoyés dans l'appel de procédure). Dans les fonctions, vous ne pouvez INSERT INTO my_log_table (message) VALUES (msg)et peut-être récupérer tous les messages de débogage qu'une fois les appels de fonction terminés (c'est-à-dire: vous êtes de retour dans la procédure)
Xenos

Cette approche est bonne mais l'écriture sur la console n'est pas efficace sur MySQL Workbench comme les IDE. car chaque instruction "select" ouvre un nouveau volet de résultats. Je pense qu'il est préférable de créer une table de journal temporaire pour enregistrer les messages d'erreur avec l'horodatage et le nom de la procédure
mustafa kemal tuna

28

Oui, il existe un outil spécialisé pour ce genre de chose - MySQL Debugger .
entrez la description de l'image ici


5
J'avais tellement hâte de l'essayer. Malheureusement, c'est une épave totale. J'obtiens le message d'erreur "la fonction coalesce n'existe pas" de mysql, en conséquence l'interface graphique se branche de manière incorrecte via le code SP (bien que MySQL l'exécute correctement). Sans parler des variables locales "DECLARE var DEFAULT value". Ils apparaissent juste comme NULL alors qu'ils ne le sont clairement pas. Oh, et aussi "Identificateur non déclaré: 'FETCH_RADIUS_DISTSORT'" où c'était une instruction compilée. Non recommandé.
kellogs

4
Ce n'est pas parfait, mais mon essai avec cela a été une expérience très différente de celle rapportée par @kellogs ci-dessus. L'outil est agréable et léger et semble faire juste le travail nécessaire sans aucune ballonnement. Ce fut une bien meilleure expérience pour moi que tous les autres outils testés (c'est-à-dire Visual Studio, Toad et dbForge Studio, qui avaient tous des défauts majeurs - décriraient tous ces derniers comme une "épave totale" en comparaison). Je ne sais pas si cela est dû au fait que la fonction en cours de débogage n'incluait aucune des constructions défectueuses ou si les problèmes ont été résolus.
Steve Chambers

2
J'ai également trouvé cet outil très utile pour déboguer mes procédures stockées.
ralfe

22

Comment déboguer une procédure stockée MySQL.

Débogueur pauvre de l'homme:

  1. Créez une table appelée logtable avec deux colonnes id INTet log VARCHAR(255).

  2. Effectuez l'auto-incrémentation de la colonne id.

  3. Utilisez cette procédure:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
        insert into logtable select 0, msg;
    END
  4. Placez ce code partout où vous souhaitez enregistrer un message dans la table.

    call log_msg(concat('myvar is: ', myvar, ' and myvar2 is: ', myvar2));

C'est un petit enregistreur rapide et sale pour comprendre ce qui se passe.



10

Le débogueur pour mysql était bon mais ce n'est pas gratuit. C'est ce que j'utilise maintenant:

DELIMITER GO$

DROP PROCEDURE IF EXISTS resetLog

GO$

Create Procedure resetLog() 
BEGIN   
    create table if not exists log (ts timestamp default current_timestamp, msg varchar(2048)) engine = myisam; 
    truncate table log;
END; 

GO$

DROP PROCEDURE IF EXISTS doLog 

GO$

Create Procedure doLog(in logMsg nvarchar(2048))
BEGIN  
  insert into log (msg) values(logMsg);
END;

GO$

Utilisation dans une procédure stockée:

call dolog(concat_ws(': ','@simple_term_taxonomy_id',  @simple_term_taxonomy_id));

utilisation de la procédure stockée:

call resetLog ();
call stored_proc();
select * from log;

8

Une autre manière est présentée ici

http://gilfster.blogspot.co.at/2006/03/debugging-stored-procedures-in-mysql.html

avec des procédures de débogage personnalisées mySql et des tables de journalisation.

Vous pouvez également simplement placer une simple sélection dans votre code et voir si elle est exécutée.

SELECT 'Message Text' AS `Title`; 

J'ai eu cette idée de

http://forums.mysql.com/read.php?99,78155,78225#msg-78225

Quelqu'un a également créé un modèle pour les procédures de débogage personnalisées sur GitHub.

Vois ici

http://www.bluegecko.net/mysql/debugging-stored-procedures/ https://github.com/CaptTofu/Stored-procedure-debugging-routines

A été mentionné ici

Comment attraper une exception dans les déclencheurs et stocker les procédures pour mysql?


7

Je place simplement des instructions select dans les zones clés de la procédure stockée pour vérifier l'état actuel des ensembles de données, puis je les commente (--select ...) ou les supprime avant la production.


7

Je suis en retard à la fête, mais j'ai apporté plus de bière:

http://ocelot.ca/blog/blog/2015/03/02/the-ocelotgui-debugger/ et https://github.com/ocelot-inc/ocelotgui

J'ai essayé, et cela semble assez stable, prenant en charge les points d'arrêt et l'inspection variable.

Ce n'est pas une suite complète (seulement 4,1 Mo) mais m'a beaucoup aidé!

Comment cela fonctionne: Il s'intègre à votre client mysql (j'utilise Ubuntu 14.04), et après avoir exécuté:

$install
$setup yourFunctionName

Il installe une nouvelle base de données sur votre serveur, qui contrôle le processus de débogage. Alors:

$debug yourFunctionName('yourParameter')

vous donnera une chance de parcourir pas à pas votre code, et de "rafraîchir" vos variables, vous pourrez mieux voir ce qui se passe dans votre code.

Conseil important: lors du débogage, vous allez peut-être changer (recréer la procédure). Après une recréation, exécutez: $ exit et $ setup avant un nouveau $ debug

Il s'agit d'une alternative aux méthodes "insert" et "log". Votre code reste exempt d'instructions de "débogage" supplémentaires.

Capture d'écran:

pas de point d'arrêt ocelot


6

MySQL Connector / Net 6.6 a une fonctionnalité pour déboguer les procédures et fonctions stockées

Installation du débogueur

Pour activer le débogueur de procédure stockée:

  • Pour Connector / Net 6.6: installez Connector / Net 6.6 et choisissez l'option Complète.
  • Pour Connector / Net 6.7 et versions ultérieures: installez le produit MySQL pour Visual Studio, auquel appartient le débogueur de procédure stockée.

Démarrage du débogueur

Pour démarrer le débogueur, procédez comme suit:

  • Choisissez une connexion dans l'Explorateur de serveurs Visual Studio.
  • Développez le dossier Procédures stockées. Seules les procédures stockées peuvent être déboguées directement. Pour déboguer une fonction définie par l'utilisateur, créez une
    procédure stockée qui appelle la fonction.
  • Cliquez sur un nœud de procédure stockée, puis cliquez avec le bouton droit de la souris et dans le menu contextuel, choisissez Debug Routine.

5

MySql Connector / NET comprend également un débogueur de procédure stockée intégré dans Visual Studio à partir de la version 6.6, vous pouvez obtenir le programme d'installation et la source ici: http://dev.mysql.com/downloads/connector/net/

Quelques documents / captures d'écran: https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

Vous pouvez suivre les annonces ici: http://forums.mysql.com/read.php?38,561817,561817#msg-561817

MISE À JOUR: MySql for Visual Studio a été séparé de Connector / NET en un produit distinct, vous pouvez le choisir (y compris le débogueur) à partir d'ici https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (toujours gratuit et open source).

AVERTISSEMENT: J'étais le développeur qui a créé le moteur de débogage des procédures stockées pour MySQL pour le produit Visual Studio.


Il y a un problème avec la chaîne de connexion multi-hôte lors de l'utilisation de MySQL et du connecteur .NET. J'ai expliqué le problème ici ... Je me demandais si quelqu'un allait se pencher -dessus? Cela a causé pas mal de problèmes pour beaucoup d'entre nous, les développeurs .Net qui utilisent MySQL ...
Hooman Bahreini

1
Désolée d'entendre cela, je ne travaille plus chez Oracle, et n'ai pas beaucoup de temps libre, je suggère de contacter le support MySQL.
Fernando Gonzalez Sanchez

4

Le premier débogueur stable pour MySQL est dans dbForge Studio pour MySQL


3

J'avais utilisé deux outils différents pour déboguer les procédures et les fonctions:

  1. dbForge - plusieurs GUI fonctionnelles de mysql.
  2. MyDebugger - outil spécialisé pour le débogage ... outil pratique pour le débogage. vote http://tinyurl.com/voteimg

3

La variable définie par l'utilisateur MySQL (partagée en session) peut être utilisée comme sortie de journalisation:

DELIMITER ;;
CREATE PROCEDURE Foo(tableName VARCHAR(128))
BEGIN
  SET @stmt = CONCAT('SELECT * FROM ', tableName);
  PREPARE pStmt FROM @stmt;
  EXECUTE pStmt;
  DEALLOCATE PREPARE pStmt;
  -- uncomment after debugging to cleanup
  -- SET @stmt = null;
END;;
DELIMITER ;
call Foo('foo');
select @stmt;

affichera:

SELECT * FROM foo

1

Toad mysql. Il existe une version freeware http://www.quest.com/toad-for-mysql/


1
J'utilise Toad depuis des années mais je ne savais pas qu'il avait des fonctionnalités spéciales pour le débogage des sprocs. Pouvez-vous clarifier comment vous utilisez Toad pour ce faire?
Cory House

Regardé Toad 6.3 pour mysql tout à l'heure, il semble qu'il y ait une fonctionnalité de débogage avec des points d'arrêt et tout. Voulez-vous dire que la fonction de débogage ne fonctionne pas? Ou peut-être que votre version est plus ancienne et n'inclut pas de fonction de débogage?
Joyce

1

Réponse correspondant à ceci par @Brad Parks Je ne suis pas sûr de la version MySQL, mais la mienne était la version 5.6, d'où quelques travaux d'ajustement:

J'ai créé une fonction debug_msgqui est une fonction (pas une procédure) et renvoie du texte (aucune limite de caractères), puis j'appelle la fonction en tant que SELECT debug_msg(params) AS my_res_set, code comme ci-dessous:

CREATE DEFINER=`root`@`localhost` FUNCTION `debug_msg`(`enabled` INT(11), `msg` TEXT) RETURNS text CHARSET latin1
    READS SQL DATA
BEGIN
    IF enabled=1 THEN
    return concat('** DEBUG:', "** ", msg);
    END IF;
END

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_func_call`(
 IN RegionID VARCHAR(20),
 IN RepCurrency INT(11),
 IN MGID INT(11),
 IN VNC VARCHAR(255)
)
BEGIN
    SET @enabled = TRUE;
    SET @mainQuery = "SELECT * FROM Users u";
    SELECT `debug_msg`(@enabled, @mainQuery) AS `debug_msg1`;
    SET @lastQuery = CONCAT(@mainQuery, " WHERE u.age>30);
    SELECT `debug_msg`(@enabled, @lastQuery) AS `debug_msg2`;
END $$
DELIMITER
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.