存储过程加游标一起使用的基本操作
1 -- 存储过程 加 游标 2 3 -- 建表 4 create table student( 5 sid varchar(8) primary key, 6 sname varchar(10), 7 sex varchar(2), 8 age int, 9 classno varchar(6) 10 ); 11 -- 表中的数据 12 insert into student values 13 ('20170101','张石瑞','男','19','201701'), 14 ('20170201','李佛','女','20','201702'), 15 ('20170202','王法无','男','19','201702') 16 17 /* 创建游标和关闭游标的四个步骤 18 -- 1、创建游标 (cur_name 游标名字) 19 declare cur_name cursor for select 语句; 20 -- 2、打开游标 21 open cur_name; 22 -- 3、提取游标数据 23 fetch cur_name [into 变量1,变量2,、、、、、]; 24 -- 4、关闭(释放)游标 25 close cur_name; 26 */ 27 -- 游标的基本提取操作 28 create PROCEDURE proc1() 29 BEGIN 30 declare cur_sid varchar(20); 31 declare cur_sname varchar(20); 32 declare cur_sex varchar(20); 33 declare cur_age varchar(20); 34 declare cur_classno varchar(20); 35 -- 1、 36 declare student_cur1 CURSOR for 37 select sid,sname,sex,age,classno from student; 38 -- 2、 39 open student_cur1; 40 -- 3、 41 fetch student_cur1 into cur_sid,cur_sname,cur_sex,cur_age,cur_classno; 42 select cur_sid,cur_sname,cur_sex,cur_age,cur_classno; 43 -- 4、 44 close student_cur1; 45 END 46 47 -- 执行存储过程 48 call proc1(); 49 -- 删除存储过程 50 drop procedure if exists proc1 51 52 53 54 -- 游标的循环遍历‘ 55 create PROCEDURE proc2() 56 BEGIN 57 declare cur_sid varchar(20); 58 declare cur_sname varchar(20); 59 declare cur_sex varchar(20); 60 declare cur_age varchar(20); 61 declare cur_classno varchar(20); 62 63 declare sum int default 0; 64 declare i int default 0; 65 -- 1、 66 declare student_cur1 CURSOR for 67 select sid,sname,sex,age,classno from student; 68 -- 2、 69 open student_cur1; 70 -- 3、 最简单的 while 遍历方法 71 select count(sid) into sum from student; 72 while i<sum DO 73 fetch student_cur1 into cur_sid,cur_sname,cur_sex,cur_age,cur_classno; 74 select cur_sid,cur_sname,cur_sex,cur_age,cur_classno; 75 set i=i+1; 76 end while; 77 -- 4、 78 close student_cur1; 79 END 80 81 -- 执行存储过程 82 call proc2(); 83 -- 删除存储过程 84 drop procedure if exists proc2 85 86 87 -- 使用 loop 遍历游标 88 create PROCEDURE proc3() 89 BEGIN 90 declare cur_sid varchar(20); 91 declare cur_sname varchar(20); 92 declare cur_sex varchar(20); 93 declare cur_age varchar(20); 94 declare cur_classno varchar(20); 95 96 declare state int default false; -- 定义表示用于判断游标是否溢出 97 -- 1、 98 declare student_cur1 CURSOR for 99 select sid,sname,sex,age,classno from student; 100 -- 2、 101 open student_cur1; 102 -- 3、 loop 遍历游标 103 cur_loop:loop -- 循环开始 104 -- 循环开始的时候提取一次 105 fetch student_cur1 into cur_sid,cur_sname,cur_sex,cur_age,cur_classno; 106 select cur_sid,cur_sname,cur_sex,cur_age,cur_classno; 107 108 if state then 109 leave cur_loop; 110 end if; 111 end loop; -- 循环结束 112 -- 4、 113 close student_cur1; 114 END 115 116 -- 执行存储过程 117 call proc3() 118 -- 删除存储过程 119 drop procedure if exists proc3 120 121 122 123 124 /* 125 fetch是获取游标当前指向的数据行,并将指针指向下一行,当游标已经指向最后一行时继续执行会造成游标溢出。 126 使用loop循环游标时,他本身是不会监控是否到最后一条数据了,像下面代码这种写法,就会造成死循环; 127 128 read_loop:loop 129 fetch cur into n,c; 130 set total = total+c; 131 end loop; 132 在MySql中,造成游标溢出时会引发mysql预定义的NOT FOUND错误,所以在上面使用下面的代码指定了当引发not found错误时定义一个continue 的事件,指定这个事件发生时修改done变量的值。 133 134 declare continue HANDLER for not found set done = true; 135 也有这样写的 136 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' set done = true; 137 所以在循环时加上了下面这句代码: 138 139 --判断游标的循环是否结束 140 if done then 141 leave read_loop; --跳出游标循环 142 end if; 143 如果done的值是true,就结束循环。继续执行下面的代码。 144 145 */ 146 147 148 149 150 151 152 153 154 -- 性别翻转 155 156 create PROCEDURE proc4() 157 BEGIN 158 declare cur_sid int; 159 declare cur_sex varchar(1); 160 161 declare state int default false; 162 -- 1、 163 declare sex_cur cursor for select sid,sex from student; 164 -- 165 declare CONTINUE HANDLER for not found set state=true; 166 -- 2、 167 open sex_cur; 168 -- 3、 169 sex_loop:LOOP -- 循环开始 170 fetch sex_cur into cur_sid,cur_sex; 171 if state then 172 leave sex_loop; 173 end if; 174 if cur_sex='男' then 175 update student set sex='女' where sid=cur_sid; 176 end if; 177 if cur_sex='女' then 178 update student set sex='男' where sid=cur_sid; 179 end if; 180 end loop; -- 循环结束 181 -- 4、 182 close sex_cur; 183 END 184 185 186 187 188 189 190 -- 执行存储过程 191 call proc4() 192 -- 删除存储过程 193 drop procedure if exists proc4 194 195 196 197 198 199 -- 表的查询 200 select * from student