MySQL存储过程的游标,事务使用
经常使用MySQL存储过程的游标进行数据操作,有些时候游标内的操作成功一半,失败一半,导致修复数据浪费更多时间,索性加入事务操作,插入失败那就都失败,成功就都成功
游标定义需要注意的是,定义游标必须放到赋值的前面,不然存储过程保存报错
CREATE DEFINER=`root`@`%` PROCEDURE `insertData`()
BEGIN
DECLARE Done INT DEFAULT 0;
declare p_name varchar(100);
DECLARE IMP_CUR CURSOR FOR SELECT name FROM studen;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET Done = 1;
#定义事务正确类型
DECLARE t_error INTEGER DEFAULT 0;
#捕捉sql错误
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;
#开始事务
START TRANSACTION;
open IMP_CUR ;
FETCH next from IMP_CUR INTO p_name;
repeat
IF NOT Done THEN
insert into class (name) values(p_name);
END IF;
FETCH next from IMP_CUR INTO imp_name;
until done end repeat;
CLOSE IMP_CUR ;
#发生错误
IF t_error = 1 THEN
#回滚事务
ROLLBACK;
select '操作成功';
ELSE
COMMIT;
sleect '操作成功';
END IF;
END
另一种游标使用方式
CREATE DEFINER=`root`@`%` PROCEDURE `p`(`param` VARCHAR(5000))
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE p_id int;
DECLARE p_name int;
DECLARE My_Cursor CURSOR FOR ( select id, name from student ); -- 定义游标并输入结果集
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- 绑定控制变量到游标,游标循环结束自动转true
OPEN My_Cursor;
myLoop: LOOP -- 开始循环体,myLoop为自定义循环名,结束循环时用到
FETCH My_Cursor into p_id,p_name; -- 将游标当前读取行的数据顺序赋予自定义变量12
IF done THEN -- 判断是否继续循环
LEAVE myLoop; -- 结束循环
END IF;
update class set student_name = p_name where student_id=p_id;
END LOOP myLoop; -- 结束自定义循环体
CLOSE My_Cursor;
END