mysql的存储过程有很多需要注意的地方,一不留神就会出错,可能调试了老半天才发现原因

1  没有return 语句

可以采用leave代替,返回直接使用select语句 比如select 1;

2.mysql的语句要严格加上分号,非执行语句的不需要加,比如begin、end、loop等

3.游标的获取状态 通常采用定义一个继续执行的处理,CONTINUE的意思就是遇到Not FOUND的异常时,会设置一个变量标志,但是程序继续执行,然后我们根据这个标志来跳出循环或者返回等等

    declare csrTransId cursor For select trans_id from tbl_fkcmd_trans where device_id=dev_id AND status='RUN';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = ;

4.事务 异常处理 mysql没有try catch 我们只能根据错误的标志自行回滚,这里有个要注意的事项,CONTINUE HANDLER FOR SQLEXCEPTION一般放在了CONTINUE HANDLER FOR NOT FOUND后面如果放在前面就会出问题了,想想为什么?

因为CONTINUE HANDLER FOR NOT FOUND通常用在游标的循环场景下,我们希望在这个场景下捕获这个“异常”然后跳出循环,mysql先捕获了这个,程序继续执行,不会将其为一个事务的异常捕获,所以CONTINUE HANDLER 具有先后顺序,有点类似try catch中的异常捕获,先捕获的异常在后面的catch语句中不在捕获。

  DECLARE t_error INTEGER DEFAULT ;
declare csrTransId cursor For select trans_id from tbl_fkcmd_trans where device_id=dev_id AND status='RUN';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = ;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=;

5.输出参数不可以和字段名同名,否则为null

下面贴上 一段完整的存储过程,仅作为示例

rt:BEGIN
-- 遍历数据结束标志
DECLARE done INT DEFAULT ; declare trans_id_tmp varchar();
DECLARE t_error INTEGER DEFAULT ;
declare csrTransId cursor For select trans_id from tbl_fkcmd_trans where device_id=dev_id AND status='RUN';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = ;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=;
-- 将结束标志绑定到游标 -- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
-- SET NOCOUNT ON; -- trans_id
set trans_id_p='';
if (dev_id is null || LENGTH(dev_id) = ) THEN
select -;
LEAVE rt;
end if;
-- Insert statements for procedure here
SELECT trans_id into trans_id_p FROM tbl_fkcmd_trans where device_id=dev_id AND cmd_code='RESET_FK' AND status='WAIT';
if(FOUND_ROWS() = ) then
select -;
LEAVE rt;
end if;
start transaction;
Open csrTransId;
read_loop: LOOP
Fetch Next From csrTransId Into trans_id_tmp;
IF done= THEN
LEAVE read_loop;
END IF;
DELETE FROM tbl_fkcmd_trans_cmd_param WHERE trans_id=trans_id_tmp;
DELETE FROM tbl_fkcmd_trans_cmd_result WHERE trans_id=trans_id_tmp;
END LOOP;
close csrTransId;
UPDATE tbl_fkcmd_trans SET status='CANCELLED', update_time = NOW() WHERE device_id=dev_id AND status='RUN';
UPDATE tbl_fkcmd_trans SET status='RESULT', update_time = now() WHERE device_id=dev_id AND cmd_code='RESET_FK';
IF t_error = THEN
ROLLBACK;
set trans_id_p='';
select -;
leave rt;
else
commit;
select ;
end if;
END

最新文章

  1. JS判断是不是手机浏览器浏览网站的网页,并自动跳转
  2. Java学习资料
  3. placeholder的兼容处理(jQuery下)
  4. 添加thrust的库后出错
  5. LAMP编译参数查看
  6. 转载:看c++ primer 学习心得
  7. Cocos2d-x——CocosBuilder官方帮助文档翻译3 动画
  8. Codeforces 553D Nudist Beach(图论,贪心)
  9. Collections.unmodifiableList()的使用与场景
  10. Remove掉Request.QueryString
  11. gmic全球移动互联网大会 全球九站已开启!
  12. Android Security
  13. 把Eclipse项目转换成Maven项目
  14. R数据分析 第一篇:温习概率论
  15. 浅入深出Vue:工具准备之PostMan安装配置及Mock服务配置
  16. LeetCode第二十一题-对两个有序链表排序
  17. 第一册:lesson ninety-three。
  18. vim 高级编辑技巧
  19. React Router教程
  20. 01-HTML5的介绍

热门文章

  1. uboot配置过程详解1
  2. Could not publish server configuration for Tomcat v6.0 Server at localhost.错误问题解决
  3. ZOJ 3488 Conic Section
  4. Redis 补充
  5. Hive——巧用transform处理复杂的字符串问题
  6. Android 进阶7:进程通信之 AIDL 的使用
  7. 剑指offer-第七章面试案例1(字符串转换为整型)
  8. Tornado输出和响应头
  9. 04:sqlalchemy操作数据库 不错
  10. setContentHuggingPriority和setContentCompressionResistancePriority的使用