mysql 存储过程 编写注意事项
2024-08-29 00:04:40
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
最新文章
- JS判断是不是手机浏览器浏览网站的网页,并自动跳转
- Java学习资料
- placeholder的兼容处理(jQuery下)
- 添加thrust的库后出错
- LAMP编译参数查看
- 转载:看c++ primer 学习心得
- Cocos2d-x——CocosBuilder官方帮助文档翻译3 动画
- Codeforces 553D Nudist Beach(图论,贪心)
- Collections.unmodifiableList()的使用与场景
- Remove掉Request.QueryString
- gmic全球移动互联网大会 全球九站已开启!
- Android Security
- 把Eclipse项目转换成Maven项目
- R数据分析 第一篇:温习概率论
- 浅入深出Vue:工具准备之PostMan安装配置及Mock服务配置
- LeetCode第二十一题-对两个有序链表排序
- 第一册:lesson ninety-three。
- vim 高级编辑技巧
- React Router教程
- 01-HTML5的介绍
热门文章
- uboot配置过程详解1
- Could not publish server configuration for Tomcat v6.0 Server at localhost.错误问题解决
- ZOJ 3488 Conic Section
- Redis 补充
- Hive——巧用transform处理复杂的字符串问题
- Android 进阶7:进程通信之 AIDL 的使用
- 剑指offer-第七章面试案例1(字符串转换为整型)
- Tornado输出和响应头
- 04:sqlalchemy操作数据库 不错
- setContentHuggingPriority和setContentCompressionResistancePriority的使用