如何调试 MySQL 存储过程?

我当前调试存储过程的过程非常简单。我创建了一个名为“ debug”的表,其中在存储过程运行时插入变量值。这允许我在脚本的给定点查看任何变量的值,但是有更好的方法来调试 MySQL 存储过程吗?

212852 次浏览

我只是简单地将 select 语句放在存储过程的关键区域中,以检查数据集的当前状态,然后在生产之前注释掉它们(—— select...)或删除它们。

我和你做过类似的事。

我通常会包含一个默认为 false 的 DEBUG 参数,我可以在运行时设置为 true。然后将调试语句包装到“ If DEBUG”块中。

我还在许多工作中使用日志表,以便检查流程和计时。我的调试代码也会在那里输出。我包括调用参数的名称,一个简短的描述,受影响的行数(如果适当) ,一个评论字段和时间戳。

好的调试工具是所有 SQL 平台的缺点之一。

是的,有一个专门的工具来处理这类事情-MySQL 调试器
enter image description here

MySQL 中有 用于调试存储过程的 GUI 工具/函数和脚本。一个像样的工具,dbForge Studio for MySQL,具有丰富的功能和稳定性。

第一个稳定的 MySQL 调试器位于 MySQL 的 dbForge Studio 中

Toad mysql 有一个免费版本 Http://www.quest.com/toad-for-mysql/

我使用了两种不同的工具来调试过程和函数:

  1. 多功能 mysql GUI。
  2. MyDebugger ——专门用于调试的工具... 用于调试的方便工具

这里提出了另一种方法

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

使用自定义调试 mySql 过程和日志表。

您还可以在代码中放置一个简单的选择,然后查看它是否被执行。

SELECT 'Message Text' AS `Title`;

我的想法来自

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

还有人为 GitHub 上的自定义调试过程创建了一个模板。

看这里

Http://www.bluegecko.net/mysql/debugging-stored-procedures/ Https://github.com/capttofu/stored-procedure-debugging-routines

在这里提到过

如何在 mysql 的触发器和存储过程中捕获任何异常?

MySql Connector/NET 还包括一个集成在 Visual Studio 中的存储过程调试器(版本6.6) , 你可以在这里找到安装程序和源代码: Http://dev.mysql.com/downloads/connector/net/

一些文档/截图: Https://dev.mysql.com/doc/visual-studio/en/visual-studio-debugger.html

你可在此浏览有关公告: Http://forums.mysql.com/read.php?38,561817,561817#msg-561817

更新: MySql for Visual Studio 已经从 Connector/NET 分离成一个独立的产品,您可以从这里选择它(包括调试器) https://dev.mysql.com/downloads/windows/visualstudio/1.2.html(仍然是免费和开源的)。

免责声明: 我是为 MySQL for Visual Studio 产品编写存储过程调试器引擎的开发人员。

可以调用以下 debug_msg过程将调试消息简单地输出到控制台:

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 ;

然后像这样运行测试:

CALL test_procedure(1,2)

这将产生以下结果:

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

如何调试 MySQL 存储过程。

穷人调试器:

  1. 创建一个名为 logtable 的表,其中包含两列 id INTlog VARCHAR(255)

  2. 使 id 列自动递增。

  3. 使用以下程序:

    delimiter //
    DROP PROCEDURE `log_msg`//
    CREATE PROCEDURE `log_msg`(msg VARCHAR(255))
    BEGIN
    insert into logtable select 0, msg;
    END
    
  4. Put this code anywhere you want to log a message to the table.

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

It's a nice quick and dirty little logger to figure out what is going on.

Mysql 的调试器很好,但并不是免费的。下面是我现在使用的:

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$

存储过程中的用法:

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

存储过程的用法:

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

MySQL Connector/Net 6.6对 调试存储过程和函数有一个特性

安装调试器

启用存储过程调试器:

  • 对于 Connector/Net 6.6: 安装 Connector/Net 6.6并选择 Complete 选项。
  • 对于 Connector/Net 6.7及更高版本: 安装存储过程调试器所属的产品 MySQL For Visual Studio。

启动调试器

要启动调试器,请执行以下步骤:

  • 在 VisualStudioServer 资源管理器中选择连接。
  • 展开“存储过程”文件夹。只有存储过程可以直接调试。若要调试用户定义函数,请创建一个存储的
    调用该函数的。
  • 单击一个存储过程节点,然后右击并从上下文菜单中选择“调试例程”。

我来晚了,但带了更多的啤酒:

Http://ocelot.ca/blog/blog/2015/03/02/the-ocelotgui-debugger/ 还有 Https://github.com/ocelot-inc/ocelotgui

我试过了,它看起来非常稳定,支持断点和变量检查。

这不是一个完整的套件(只有4,1 Mb) ,但帮了我很多!

工作原理: 它与 mysql 客户端集成(我使用的是 Ubuntu 14.04) ,执行后:

$install
$setup yourFunctionName

它在服务器上安装一个新的数据库,控制调试过程。因此:

$debug yourFunctionName('yourParameter')

将给你一个机会,一步一步走你的代码,并“刷新”您的变量,你可以更好地查看什么是正在进行的内部代码。

重要提示: 在调试时,可能会进行更改(重新创建过程)。重新创建之后,在新的 $debug 之前执行: $exit 和 $setup

这是“插入”和“日志”方法的替代方法。 您的代码仍然没有额外的“调试”指令。

截图:

ocelot breakpoint stepping

回答相应的 这个由@Brad Parks 提供 MySQL 版本不确定,但我的版本是5.6,因此稍微做了一些调整:

我创建了一个函数 debug_msg,它是函数(不是过程) ,返回文本(没有字符限制) ,然后把函数调用为 SELECT debug_msg(params) ,调用为 my_res_set,代码如下:

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

MySQL 用户定义的变量(在会话中共享)可以用作日志输出:

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;

将输出:

SELECT * FROM foo