您如何调试MySQL存储过程?


125

我当前用于调试存储过程的过程非常简单。我创建一个名为“ debug”的表,在该表中,它会在存储过程运行时插入变量值。这使我可以在脚本中的给定位置查看任何变量的值,但是是否有更好的方法来调试MySQL存储过程?


2
非Windows用户是否有任何GUI选项?只需要运行Windows副本即可调试存储过程就可以了。如果您要回滚的事务中的大多数表插入选项都会失败。
代码憎恶者

Answers:


44

我做的事情和你很相似。

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

我还将日志表与许多工作结合使用,以便我可以查看流程和时间安排。我的调试代码也在那里输出。我包括调用参数名称,简短描述,受影响的行数(如果适用),注释字段和时间戳。

好的调试工具是所有SQL平台的不幸失败之一。


3
并非所有平台@Bob Probst,sybase调试工具都非常适合使用触发器和存储过程的断点调试
Anup 2015年

69

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

8
这似乎对FUNCTIONS不起作用,我也不知道为什么。它总是给出“错误代码:1415。不允许从函数返回结果集”。有没有追索权?
Patrick M

1
当此调试过程依赖于它时,@ PatrickM函数不能返回行(“结果”)(调试消息是过程调用中返回的结果集)。在函数中,INSERT INTO my_log_table (message) VALUES (msg)函数调用结束后(即:您返回过程中),您可能只能并且可能会检索所有调试消息
Xenos

这种方法很好,但是在控制台上编写对IDE等MySQL Workbench无效。因为每个“选择”语句都会打开新的结果窗格。我认为最好创建一个临时日志表来记录带有时间戳和过程名称的错误消息
mustafa kemal tuna

28

是的,有专门的工具可用于此类事情-MySQL Debugger
在此处输入图片说明


5
我是如此渴望尝试。不幸的是,这完全是残骸。我从mysql突然收到“功能合并不存在”错误消息,结果是GUI通过SP代码错误地分支了(尽管MySQL正确运行了)。更不用说“ DECLARE var DEFAULT value”局部变量了。当它们显然不是时,它们只是显示为NULL。哦,还有“未声明的标识符:'FETCH_RADIUS_DISTSORT'”,它是已编译的语句。不建议。
2013年

4
这不是完美的,但是我的尝试与上面@kellogs报告的经历截然不同。该工具既美观又轻巧,似乎可以轻松完成所需的工作。对我而言,这比试用的任何其他工具都要好得多(例如,Visual Studio,Toad和dbForge Studio,它们都具有主要缺陷-相比之下,所有这些都将它们描述为“总残骸”)。不知道这是因为要调试的函数不包含任何错误的构造,还是问题是否已解决。
史蒂夫·钱伯斯

2
我还发现此工具对于调试存储过程非常有用。
ralfe

22

如何调试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. 将此代码放在您要在表中记录消息的任何位置。

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

这是一个不错的快速而又肮脏的小记录器,它可以判断出发生了什么。



10

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;

8

这里介绍了另一种方法

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如何在触发器和存储过程中捕获异常?


7

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


7

我参加聚会很晚,但是带了更多啤酒:

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')

将为您提供逐步浏览代码的机会,并“刷新”您的变量,您可以更好地查看代码内部的情况。

重要提示:调试时,也许您会更改(重新创建过程)。重新创建后,执行:$ exit和$ setup,然后执行新的$ debug

这是“插入”和“日志”方法的替代方法。您的代码没有其他“调试”指令。

屏幕截图:

豹猫断点步进


6

MySQL Connector / Net 6.6具有调试存储过程和函数的功能

安装调试器

要启用存储过程调试器:

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

启动调试器

要启动调试器,请按照下列步骤操作:

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

5

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

更新:从连接器/ Visual Studio中被分裂净流入一个单独的产品MySQL的,你可以从这里挑吧(含调试)https://dev.mysql.com/downloads/windows/visualstudio/1.2.html (仍免费和开源)。

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


使用MySQL和Connector .NET时,多主机连接字符串存在问题。我已经在这里解释了这个问题..我想知道是否有人会对此进行调查?这给我们许多使用MySQL的.NET开发人员带来了很多问题……
Hooman Bahreini 19/12/18

1
很抱歉听到这样的消息,我不再在Oracle工作,并且没有很多空闲时间,我建议与MySQL支持联系。
费尔南多·冈萨雷斯·桑切斯,

4

MySQL的第一个稳定调试器在dbForge Studio for MySQL中


3

我曾经使用两种不同的工具来调试过程和功能:

  1. dbForge-许多功能强大的mysql GUI。
  2. MyDebugger-用于调试的专用工具...用于调试的便捷工具。投票http://tinyurl.com/voteimg

3

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

1

蟾蜍mysql。有一个免费版本 http://www.quest.com/toad-for-mysql/


1
我已经使用Toad多年了,但是我不知道它具有调试proc的任何特殊功能。您能说明一下如何使用Toad这样做吗?
2012年

刚刚看过Toad 6.3 for mysql,看起来好像有带有断点的调试功能。您是说调试功能不起作用吗?还是您的版本较旧且不包含调试功能?
乔伊斯2012年

1

@Brad Parks 对应于此的答案不确定MySQL版本,但是我的版本是5.6,因此需要进行一些调整:

我创建了一个函数debug_msg,该函数是函数(不是过程)并返回文本(没有字符限制),然后将该函数称为SELECT debug_msg(参数)AS 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.