异常处理是存储过程里对各类错误异常进行捕获和自定义操作的机制,是有两种类型:exit——遇到错误就会退出执行后续的,continue——遇到错误会忽略错误继续执行后续。

下面举例说明:比如有一个存储过程p_insert_excep,有两个输入参数:s_name varchar(20),i_age int

begin 
     declare exit handler for sqlexception,sqlwarning,not found select 'haha,error!!!'; #定义一个错误异常,当有sqlexception异常,sqlwarning警告,not found没有找到这3种错误时,退出执行,输出一个错误信息。
     insert into employee(name,age) values(s_name,i_age); #一个插入记录
     select 'insert ok'; #后续操作,输出一个成功信息。
 end

执行测试:

mysql 存储过程抛出异常 mysql存储过程主动抛出异常_sql

第一个是输入的2个正确参数,第二个输入了一个错误参数NULL,因为字段不允许NULL,所以就出错了。

当我们修改下这个存储过程,把异常处理里的exit改成continue

mysql 存储过程抛出异常 mysql存储过程主动抛出异常_字段_02

然后再测试执行:

mysql 存储过程抛出异常 mysql存储过程主动抛出异常_sql_03

可以看到,这时虽然输入参数有错误,执行语句出错,但是依然执行了后面的打印成功语句。这就是continue的区别。

-------------------------------------

游标就是一个用于存储每次查询结果集的类型,可以通过它来循环读取所有的结果集。它有声明declare,打开open,获取fetch,关闭close四个命令操作。

下面用一个存储过程来演示游标的具体操作,p_getemp_cursor存储过程有一个输出参数out num int,获取总的记录数目。

begin 
     #因为该字段有中文,所以要设置编码格式utf8
     declare e_name varchar(50) CHARACTER set utf8;
     declare e_age int;
     declare d_name varchar(20) CHARACTER set utf8;
     declare has_data int default 1; #设置has_data标志,默认是1,表示有记录。
     declare emp_result cursor for #定义一个游标
     select e.name,e.age,d.name 
     from employee e left join department d 
     on e.dept_id=d.id; 
     #定义exit异常,当出现not found错误时,设置has_data为0,并退出。
     #如是continue遇到错误会忽略错误继续执行。
     declare exit handler for not found set has_data=0; 
     set num=0; #累加的记录数目
     open emp_result; #打开游标
         repeat #repeat循环
             fetch emp_result into e_name,e_age,d_name; #依次获取每个游标所指向的记录数据。
             if d_name is NULL THEN #如员工记录的部门没有找到,就是如为NULL时,修改为未知。
             set d_name='未知'; #如字段为NULL,则在下面concat字符串连接,则整个为NULL。
             end if;
             set num=num+1; #每获取一条记录后,累加1
             select concat('第',num,'个员工:',' 名字=',e_name,' 年龄=',e_age,' 部门=',d_name)
             as 员工具体信息;
             until has_data=0 #退出repeat循环的条件until,has_data=0
         end repeat; #结束repeat循环
     close emp_result; #关闭游标
 end

测试执行:

mysql> call p_getemp_cursor(@tsum);
mysql> select @tsum;

mysql 存储过程抛出异常 mysql存储过程主动抛出异常_存储过程_04