这两天在作一些简单的存储过程,之前并未涉及过,现学现卖,碰到了很多问题,找了不少资料,也差很少解决了,废话很少说,但愿用本身的失败经验给猿们提供点帮助。函数
1. select into 致使游标处理未所有完成spa
#通常来说,咱们会在某个过程(带有游标或其余循环操做)开始以前定义一个处理完毕的标识code
DECLARE done INT DEFAULT 0;递归
#设置游标信息 (以查询 a 表 id 为实例) it
DECLARE a_id INT DEFAULT 0;
DECLARE b_id INT DEFAULT 0;io
DECLARE cur CURSOR FOR (
SELECT ` id` FROM `a_table`;
); table
#然而通常咱们也会在出现错误或者其余状况下重置done的值,以下:function
#出现异常(SQLSTATE 02000 | NOT FOUND)
DECLARE CONTINUE HANDLER for SQLSTATE '02000' SET done = 1;class
#而后开始游标变量
OPEN cur;
#获取第一层游标
FETCH cur INTO a_id;
#开始循环处理(While)
WHILE (done = 0) DO
#查询关联信息(这句在某些状况下会出现错误,致使游标结束)
SELECT `id` INTO b_id from `b_table` WHERE `a_id` = a_id;
#获取下一层游标,并继续循环
FETCH cur INTO o_model_name;
#结束循环处理
END WHILE;
#结束游标
CLOSE cur;
废话说了这么多,写了个简单的例子,简单的说说会出现问题的缘由,正常来讲,当b_table中不存在a_id对应的ID值时,将返回null,但因为DECLARE CONTINUE HANDLER for SQLSTATE '02000' SET done = 1;当出现查询为null的状况时,将会重置done为1,从而不在执行后面的游标,解决方案以下:
SELECT `id` INTO b_id from `b_table` WHERE `a_id` = a_id;
更改成
SET b_id = (SELECT `id` FROM `b_table` WHERE `a_id` = a_id);
后续逻辑可直接判断b_id的值
IF b_id != '' THEN
#处理逻辑
END IF;
2. function(函数) 与 PROCEDURE(过程)的不一样调用方法
function 采用 SELECT 调用,通常会返回返回值,因此最好先定义一个变量用于储存返回值(若是须要),如带参数可直接对应赋值参数便可。
DECLARE a_result VARCHAR(100) DEFAULT '';
SELECT function_A([param_1,param_2]) INTO a_result;
procedure 采用 CALL 调用,没有返回值,主要处理逻辑,可传参数,特别注意的是:请留意 IN ,OUT ,INOUT三种模式,具体区别百度一下,讲的比我清楚。
DECLARE param_1 INT DEFAULT 0;
CALL procedure_A(param_1);
3. 递归操做
说实话刚开始使用递归是真把我难到了,网上也没有准确的操做方法,慢慢摸索才理清楚,这里也不出例子了,其实就是结合function(函数) 与 PROCEDURE(过程)就能完美的呈现递归操做,这里强调一点,当递归操做时,通常会报
ERROR 1456 (HY000): Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine
等错误,那是由于默认状况下是不容许使用递归操做的,这里须要在须要递归操做前生命一个系统变量:
SET @@max_sp_recursion_depth = 100;
后面的数值根据本身的状况设置,表示想要递归的层级
总结:新熟悉一个东西都会有很大的难度,可是网上已经有不少前辈给的方法解决,你们必定要多动手多了解,可能我这里有说的错误的地方,但愿多多理解,有问题就回复,我好更改,哈哈。