¿Cómo se depuran los procedimientos almacenados de MySQL?


125

Mi proceso actual para depurar procedimientos almacenados es muy simple. Creo una tabla llamada "depuración" donde inserto valores variables del procedimiento almacenado mientras se ejecuta. Esto me permite ver el valor de cualquier variable en un punto dado del script, pero ¿hay una mejor manera de depurar los procedimientos almacenados de MySQL?


2
¿Hay alguna opción de GUI para usuarios que no son de Windows? Tener que ejecutar una copia de Windows solo para depurar los procedimientos almacenados es un salto. Y la mayoría de las opciones de inserción de tabla fallan si está en una transacción que está a punto de deshacer.
Código abominador

Respuestas:


44

Hago algo muy parecido a ti.

Por lo general, incluiré un parámetro DEBUG que por defecto es falso y puedo establecerlo en verdadero en tiempo de ejecución. Luego, envuelva las declaraciones de depuración en un bloque "DEPURAR"

También utilizo una tabla de registro con muchos de mis trabajos para poder revisar los procesos y el tiempo. Mi código de depuración también se muestra allí. Incluyo el nombre del parámetro de llamada, una breve descripción, los recuentos de filas afectados (si corresponde), un campo de comentarios y una marca de tiempo.

Las buenas herramientas de depuración son una de las fallas tristes de todas las plataformas SQL.


3
No todas las plataformas @Bob Probst, las herramientas de depuración de Sybase son bastante decentes con depuración de punto de interrupción para disparadores y procedimientos almacenados
Anup

69

Se debug_msgpuede llamar al siguiente procedimiento para simplemente enviar un mensaje de depuración a la consola:

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 ;

Luego ejecute la prueba así:

CALL test_procedure(1,2)

Resultará en la siguiente salida:

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

8
Esto no parece funcionar para FUNCTIONS y no tengo idea de por qué. Siempre da "Código de error: 1415. No se permite devolver un conjunto de resultados de una función". ¿Hay algún recurso?
Patrick M

1
@PatrickM Functions no puede devolver filas ("resultado") mientras este procedimiento de depuración se basa en él (los mensajes de depuración son conjuntos de resultados devueltos en la llamada al procedimiento). En funciones, puede INSERT INTO my_log_table (message) VALUES (msg)recuperar y recuperar todos los mensajes de depuración una vez que finalizan las llamadas a funciones (es decir, está de vuelta en el procedimiento)
Xenos

Este enfoque es bueno, pero escribir en la consola no es efectivo en MySQL Workbench como IDEs. porque cada declaración "select" abre un nuevo panel de resultados. Creo que es mejor crear una tabla de registro temporal para registrar mensajes de error con marca de tiempo y nombre del procedimiento
mustafa kemal atún

28

Sí, hay herramientas especializadas para este tipo de cosas: MySQL Debugger .
ingrese la descripción de la imagen aquí


55
Estaba tan ansioso por probarlo. Lamentablemente es un desastre total. Recibo el mensaje de error "la fusión de funciones no existe" supuestamente de mysql, como resultado la GUI se ramifica incorrectamente a través del código SP (aunque MySQL lo ejecuta correctamente). Sin mencionar las variables locales "DECLARE var DEFAULT value". Simplemente aparecen como NULL cuando claramente no lo son. Ah, y también "Identificador no declarado: 'FETCH_RADIUS_DISTSORT'" donde se trataba de una declaración compilada. No recomendado.
Kellogs

44
No es perfecto, pero mi prueba con esto ha sido una experiencia muy diferente a la reportada por @kellogs arriba. La herramienta es agradable y liviana y parece hacer el trabajo necesario sin hinchazón. Fue una experiencia mucho mejor para mí que cualquiera de las otras herramientas probadas (es decir, Visual Studio, Toad y dbForge Studio, todas las cuales tenían fallas importantes; en comparación, describiría todo esto como un "desastre total"). No estoy seguro de si esto se debe a que la función que se está depurando no incluía ninguna de las construcciones defectuosas o si los problemas se han solucionado.
Steve Chambers

2
También encontré que esta herramienta es bastante útil para depurar mis procedimientos almacenados.
ralfe

22

Cómo depurar un procedimiento almacenado de MySQL.

Pobre depurador del hombre:

  1. Cree una tabla llamada logtable con dos columnas, id INTy log VARCHAR(255).

  2. Haga que la columna de identificación aumente automáticamente.

  3. Use este procedimiento:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
        insert into logtable select 0, msg;
    END
  4. Coloque este código en cualquier lugar donde desee registrar un mensaje en la tabla.

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

Es un pequeño registrador rápido y sucio para descubrir lo que está sucediendo.



10

El depurador para mysql fue bueno pero no es gratis. Esto es lo que uso ahora:

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$

Uso en procedimiento almacenado:

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

uso del procedimiento almacenado:

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

8

Aquí se presenta otra forma

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

con procedimientos personalizados de depuración mySql y tablas de registro.

También puede simplemente colocar una selección simple en su código y ver si se ejecuta.

SELECT 'Message Text' AS `Title`; 

Tengo esta idea de

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

También alguien creó una plantilla para procedimientos de depuración personalizados en GitHub.

Mira aquí

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

Fue mencionado aquí

¿Cómo detectar alguna excepción en los desencadenantes y los procedimientos de almacenamiento para mysql?


7

Simplemente coloco sentencias select en áreas clave del procedimiento almacenado para verificar el estado actual de los conjuntos de datos y luego comentarlos (- seleccionar ...) o eliminarlos antes de la producción.


7

Llego tarde a la fiesta, pero traje más cerveza:

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

Lo intenté, y parece bastante estable, admitiendo puntos de interrupción e inspección variable.

No es una suite completa (solo 4,1 Mb), ¡pero me ayudó mucho!

Cómo funciona: se integra con su cliente mysql (estoy usando Ubuntu 14.04), y después de ejecutar:

$install
$setup yourFunctionName

Instala una nueva base de datos en su servidor, que controla el proceso de depuración. Entonces:

$debug yourFunctionName('yourParameter')

le dará la oportunidad de recorrer paso a paso su código y, al "actualizar" sus variables, podrá ver mejor lo que sucede dentro de su código.

Consejo importante: durante la depuración, quizás cambie (vuelva a crear el procedimiento). Después de una recreación, ejecute: $ exit y $ setup antes de un nuevo $ debug

Esta es una alternativa a los métodos de "inserción" y "registro". Su código permanece libre de instrucciones adicionales de "depuración".

Captura de pantalla:

escalonamiento de punto de ruptura


6

MySQL Connector / Net 6.6 tiene una función para depurar procedimientos y funciones almacenados

Instalar el depurador

Para habilitar el depurador de procedimiento almacenado:

  • Para Connector / Net 6.6: Instale Connector / Net 6.6 y elija la opción Completa.
  • Para Connector / Net 6.7 y posterior: instale el producto MySQL para Visual Studio, al que pertenece el depurador de procedimientos almacenados.

Inicio del depurador

Para iniciar el depurador, siga estos pasos:

  • Elija una conexión en el Visual Studio Server Explorer.
  • Expanda la carpeta Procedimientos almacenados. Solo los procedimientos almacenados se pueden depurar directamente. Para depurar una función definida por el usuario, cree un
    procedimiento almacenado que llame a la función.
  • Haga clic en un nodo de procedimiento almacenado, luego haga clic con el botón derecho y en el menú contextual elija Debut Routine.

5

MySql Connector / NET también incluye un depurador de procedimientos almacenados integrado en Visual Studio a partir de la versión 6.6. Puede obtener el instalador y la fuente aquí: http://dev.mysql.com/downloads/connector/net/

Alguna documentación / capturas de pantalla: https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

Puede seguir los anuncios aquí: http://forums.mysql.com/read.php?38,561817,561817#msg-561817

ACTUALIZACIÓN: MySql for Visual Studio se dividió desde Connector / NET en un producto separado, puede elegirlo (incluido el depurador) desde aquí https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (todavía libre y de código abierto).

DESCARGO DE RESPONSABILIDAD: Fui el desarrollador que creó el motor de depuración de procedimientos almacenados para MySQL para el producto Visual Studio.


Hay un problema con la cadena de conexión de host múltiple cuando se usa MySQL y Connector .NET. He explicado el problema aquí ... Me preguntaba si alguien va a investigar esto. Esto ha causado bastante problema para muchos de nosotros. Desarrolladores .Net que usan MySQL ...
Hooman Bahreini

1
Lamento escuchar eso, ya no trabajo en Oracle y no tengo mucho tiempo libre, le sugiero que se ponga en contacto con el soporte de MySQL.
Fernando González Sánchez

4

El primer depurador estable para MySQL está en dbForge Studio para MySQL


3

Había usado dos herramientas diferentes para depurar procedimientos y funciones:

  1. dbForge - muchas funcionalidades mysql GUI.
  2. MyDebugger: herramienta especializada para la depuración ... herramienta práctica para la depuración. votar http://tinyurl.com/voteimg

3

La variable definida por el usuario MySQL (compartida en la sesión) podría usarse como salida de registro:

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;

dará salida:

SELECT * FROM foo

1

Sapo mysql. Hay una versión gratuita http://www.quest.com/toad-for-mysql/


1
He usado Toad durante años, pero no sabía que tenía características especiales para depurar sprocs. ¿Puedes aclarar cómo usas Toad para hacerlo?
Cory House

Miramos Toad 6.3 para mysql en este momento, parece que hay una función de depuración con puntos de interrupción y todo. ¿Quiere decir que la función de depuración no funciona? ¿O tal vez su versión es anterior y no incluye la función de depuración?
Joyce

1

Respuesta correspondiente a esto por @Brad Parks No estoy seguro acerca de la versión de MySQL, pero la mía era 5.6, por lo tanto, un poco de ajuste funciona:

Creé una función debug_msgque es función (no procedimiento) y devuelve texto (sin límite de caracteres) y luego llamo a la función como SELECT debug_msg(params) AS my_res_set, código de la siguiente manera:

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.