如何查看 MySQL 存储过程中的错误?
关于将 MySQL 存储过程与事务一起使用,我在获取错误输出时遇到问题。
问题是我需要设置一个 exit_handler 来在任何失败时回滚事务。但是当我这样做时,如果出现问题,我不会收到任何错误输出。例如,如果我不小心传递了 NULL 值并尝试将其插入非空字段。
我使用返回值以编程方式指示成功或失败,但这并不能告诉我实际出了什么问题。
我正在使用 Perl DBI 与 MySQL 对话。我在生产服务器上使用 MySQL 5.0.92,在开发服务器上使用 MySQL 5.0.51a。升级到较新版本的 MySQL 在政治上是站不住脚的。
这是一个简化的示例:
DELIMITER //
CREATE PROCEDURE pmt_new(
app_id varchar(40),
out ret tinyint unsigned,
out pmt_req_id int(10) unsigned)
BEGIN
DECLARE v_pmt_req_type int(10) unsigned;
DECLARE exit handler for not found, sqlwarning, sqlexception rollback;
set ret=1;
START TRANSACTION;
SELECT pmt_type INTO v_pmt_req_type FROM pmt_req_types WHERE pmt_req_name = 'Name 1';
INSERT INTO pmt_reqs (pmt_req_id, pmt_req_type, app_id)
values (null, v_pmt_req_type, app_id);
set pmt_req_id = last_insert_id();
INSERT INTO other (pmt_req_id) values (pmt_req_id);
COMMIT;
set ret=0;
END//
DELIMITER ;
With regards to using MySQL stored procedures with transactions, and I am having a problem getting error output.
The problem is that I need to set an exit_handler to roll back the transaction if anything fails. But when I do this, I don't get any error output if something goes wrong. For example if I accidentally pass a NULL value and try to insert it into a non-null field.
I am using a return value to programmatically indicate success or failure, however this does nothing to tell me what actually went wrong.
I am using Perl DBI to talk to MySQL. I am using MySQL 5.0.92 on the production server and MySQL 5.0.51a on the development server. Upgrading to a newer version of MySQL is politically untenable.
This is a simplified example:
DELIMITER //
CREATE PROCEDURE pmt_new(
app_id varchar(40),
out ret tinyint unsigned,
out pmt_req_id int(10) unsigned)
BEGIN
DECLARE v_pmt_req_type int(10) unsigned;
DECLARE exit handler for not found, sqlwarning, sqlexception rollback;
set ret=1;
START TRANSACTION;
SELECT pmt_type INTO v_pmt_req_type FROM pmt_req_types WHERE pmt_req_name = 'Name 1';
INSERT INTO pmt_reqs (pmt_req_id, pmt_req_type, app_id)
values (null, v_pmt_req_type, app_id);
set pmt_req_id = last_insert_id();
INSERT INTO other (pmt_req_id) values (pmt_req_id);
COMMIT;
set ret=0;
END//
DELIMITER ;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您不仅需要在退出处理程序中进行回滚,还需要返回一些内容...
您当前已将
其更改为类似...
在 5.5 中,他们添加了 SIGNAL/RESIGNAL 语句,以便您可以“返回”错误,但之前您必须推出自己的解决方案。如果需要,您可以声明多个退出处理程序以更好地定制输出,或者设置您自己的错误表,您可以从中提取错误。
您还可以在存储过程中进行输入测试。想知道app_id是否为空?
这样做会添加另一个输出参数,但会为您提供更好的信息。您可以对多个退出处理程序执行相同的操作。
Instead of just doing a rollback in your exit handler you need to return something as well...
You currently have
Change it to something like...
In 5.5 they added the SIGNAL/RESIGNAL statements so you could 'return' an error but prior versions you have to kind of roll your own solution. If you need you can declare multiple exit handlers to tailor the output better, or setup your own error table you can pull from.
You can also do input testing inside your stored procedure. Want to know if app_id is null?
Doing it this way adds another out parameter, but gives you much better information. You could do the same with multiple exit handlers.