一、游标
游标(CURSOR)是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、OPEN、FETCH 和 CLOSE,其语法分别如下。
声明游标
DECLARE 游标名称 CURSOR FOR 查询语句 ;
打开游标
OPEN 游标名称 ;
获取游标记录
FETCH 游标名称 INTO 变量 [, 变量 ] ;
关闭游标
CLOSE 游标名称 ;
例子:
create procedure p11()
begin
#创建存储员工信息的变量
declare v_name varchar(20);
declare v_id int;
declare v_sal double;
declare v_job varchar(50);
#1.声明游标
DECLARE c_emp CURSOR FOR select empno,ename,job,sal from emp;
#2.打开游标
open c_emp;
#3.提取数据,fetch一次就只能提取一行记录
fetch c_emp into v_id,v_name,v_job,v_sal;
select v_id,v_name,v_job,v_sal;
#4.关闭游标
close c_emp;
end;
但是我们上面的存储过程只获取了一条数据,如果要获取所有记录,那我们就要使用循环获取
create procedure p12()
begin
#创建存储员工信息的变量
declare v_name varchar(20);
declare v_id int;
declare v_sal double;
declare v_job varchar(50);
#1.声明游标
DECLARE c_emp CURSOR FOR select empno,ename,job,sal from emp;
#2.打开游标
open c_emp;
#循环获取数据
while true do
#3.提取数据,fetch一次就只能提取一行记录
fetch c_emp into v_id,v_name,v_job,v_sal;
select v_id,v_name,v_job,v_sal;
end while;
#4.关闭游标
close c_emp;
end;
执行
call p12();
发现报错了,这是因为我们在存储过程中使用while死循环,根本没有退出循环的代码,要想解决这个问题,就需要通过MySQL中提供的 条件处理程序 Handler 来解决。
二、数据处理条件
条件处理程序(Handler)可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤。具体 语法为:
DECLARE handler_type HANDLER FOR condition_value[...]
sp_statement;
handler_type的取值:
CONTINUE: 继续执行当前程序
EXIT : 终止执行当前程序
condition_value(参数指明错误类型)的取值:
sqlstate_value :包含5个字符串错误值, 比如02000
condition_name : 表示 DECLARE 定义的错误条件名称;
SQLWARNING: 匹配所有以 01 开头的 sqlstate_value 值
NOT FOUND: 匹配所有以 02 开头的 sqlstate_value 值;
SQLEXCEPTION : 匹配所有没有被 SQLWARNING 或 NOT FOUND 捕获的 sqlstate_value 值;
mysql_error_code: 匹配数值类型错误代码。
sp_statement : 为程序语句段,表示在遇到定义的错误时,需要执行的一些存储过程或函数。
下面是定义处理程序的几种方式,代码如下:
#方法一:捕获 sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info='CAN NOT FIND';
#方法二:捕获 mysql_error_code
DECLARE CONTINUE HANDLER FOR 1146 SET @info='CAN NOT FIND';
#方法三:先定义条件,然后调用
DECLARE can_not_find CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR can_not_find SET @info='CAN NOT FIND';
#方法四:使用 SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR';
#方法五:使用 NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info='CAN NOT FIND';
#方法六:使用 SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';
上述代码是 6 种定义处理程序的方法。
捕获 sqlstate_value 值。如果遇到 sqlstate_value 值为 42S02,执行 CONTINUE 操作,并且输出“CAN NOT FIND”信息。
捕获 mysql_error_code 值。如果遇到 mysql_error_code 值为 1146, 执行 CONTINUE 操作,并且输出“CAN NOT FIND”信息。
先定义条件,然后再调用条件。这里先定义 can_not_find 条件,遇到 1146 错误就执行 CONTINUE 操作。
使用 SQLWARNING。SQLWARNING 捕获所有以 01 开头的 sqlstate_value 值,然后执行 EXIT 操作,并且输出“ERROR"信息。
使用 NOT FOUND。NOT FOUND 捕获所有以 02 开头的 sqlstate_value 值,然后执行 EXIT 操作,并且输出“CAN NOT FIND”信息。
使用 SQLEXCEPTION。 SQLEXCEPTION 捕获所有没有被 SQLWARNING 或 NOT FOUND 捕获的 sqlstate_value 值,然后执行 EXIT 操作,并且输出“ERROR”信息。
例子:
create procedure p13()
begin
#创建存储员工信息的变量
declare v_name varchar(20);
declare v_id int;
declare v_sal double;
declare v_job varchar(50);
#1.声明游标
DECLARE c_emp CURSOR FOR select empno,ename,job,sal from emp;
#声明条件处理程序 : 当SQL语句执行抛出的状态码为NOT FOUND时,将关闭游标c_emp,并退出
DECLARE EXIT HANDLER FOR NOT FOUND close c_emp;
#2.打开游标
open c_emp;
#循环获取数据
while true do
#3.提取数据,fetch一次就只能提取一行记录
fetch c_emp into v_id,v_name,v_job,v_sal;
select v_id,v_name,v_job,v_sal;
end while;
#4.关闭游标
close c_emp;
end;