重复句子
REPEAT语句是一个循环语句,自带条件判断。 每一句执行完之后,都会进行条件判断。 如果为真,则退出循环sql 查看存储过程脚本,否则继续循环。 (类似于Java中的dowhile循环)
句型:
[别名:] REPEAT
处理语句
UNTIL 条件判断
END REPEAT [别名]
例子:
CREATE PROCEDURE test5()
BEGIN
SET @num=0;
add_num:REPEAT
SET @num=@num+1;
UNTIL @num=10 END REPEAT add_num;
END;
WHILE句
WHILE语句也是一个循环,自带条件判断。 与REPEAT语句不同的是WHILE语句会先进行条件判断。 当判断条件为真时,循环中的单词和句子会继续执行,如果为假,则直接退出循环。 (类似于 Java 中的 while 循环)
句型:
[别名:] WHILE 条件判断 DO
处理逻辑
END WHILE [别名]
例子:
CREATE PROCEDURE test6()
BEGIN
SET @num=0;
add_num:WHILE @num<10 DO
SET @num=@num+1;
END WHILE add_num;
END;
光标
游标用于逐行处理查询的结果集。
游标的声明必须出现在HANDLER声明之前,变量和条件声明之后。
创建游标:
DECLARE 游标名称 CURSOR FOR sql查询;
打开游标:
OPEN 游标名称;
使用游标:
FETCH 游标名称 INTO 变量1 [,变量2]...
将结果集中的数据保存到对应的变量中。 第一次使用游标时,默认读取结果集的第一行,通常配合循环语句逐行处理整个结果集。
关闭光标:
CLOSE 游标名称;
CLOSE 释放游标使用的所有内部内存和资源,因此每个游标在不再需要时都应关闭。 游标关闭后就不能再使用了。 如果需要使用,需要重新打开游标。
例子
查询tb_student表,将所有中学生姓名拼接成一个字符串,并设置在变量@name_Str中。
CREATE PROCEDURE test7()
BEGIN
-- 声明局部变量student_name,用于接收数据集中的数据
DECLARE student_name VARCHAR(10);
-- 声明局部变量done,用于判断是否退出循环,默认值为FALSE
DECLARE done INT DEFAULT FALSE;
-- 声明游标my_cursor
DECLARE my_cursor CURSOR FOR SELECT `name` FROM tb_student;
-- 声明continue handler句柄,当出现SQLSTATE "02000"时将done设置为TRUE
DECLARE CONTINUE HANDLER FOR SQLSTATE "02000" SET done = TRUE;
-- 设置用户变量@name_Str为空字符串
SET @name_Str="";
-- 打开游标
OPEN my_cursor;
-- 开始LOOP循环
concat_name:LOOP
-- 将数据集中的一行数据存放到指定的变量中
FETCH my_cursor INTO student_name;
-- 判断是否退出循环
IF done THEN LEAVE concat_name;
END IF;
-- 连接学生名称字符串
SET @name_Str = CONCAT(@name_Str,student_name);
END LOOP concat_name;
-- 关闭游标
CLOSE my_cursor;
END;
结果:
mysql> call test7();
Query OK, 0 rows affected
mysql> select @name_Str;
+----------------------+
| @name_Str |
+----------------------+
| 小明小米小看小阿小鬼 |
+----------------------+
关于 SQLSTATE "02000"
使用游标时sql 查看存储过程脚本,可以使用FETCH将数据集中的数据保存到一个变量中进行处理,当整个数据集已经被FETCH后,再去FETCH会抛出异常:
1329 - No data - zero rows fetched, selected, or processed
这个异常对应的SQLSTATE是02000,所以需要指定一个句柄来捕获这些异常给flag参数,然后就可以通过这个flag来判断循环读取数据集的结束。
异常信息详见:ErrorReference