游标的概念有点类似迭代器的概念,但不是数组或者列表里下标的概念。
一个游标对应一条查询语句,当查询语句的结果集有多条记录时,可以使用游标遍历结果集,根据这个游标取出它对应记录的信息,随后再移动游标,让它执向下一条记录。游标既可以用在存储函数中,也可以用在存储过程中。
游标的使用大致分为以下四个步骤:
- 创建游标;
- 打开游标;
- 通过游标访问记录;
-
1、游标的基本使用
1.1 创建游标
格式:
DECLARE 游标名称 CURSOR FOR 查询语句;
1.2 打开游标
格式:
OPEN 游标名称;
1.3 通过游标访问记录
格式:
FETCH 游标名 INTO 变量1, 变量2, ... 变量n
注意:
每调用一次
FETCH
语句,游标就移动到下一条记录的位置,因此如果想通过游标遍历结果集需要不断地FETCH
。1.4 关闭游标
格式:
CLOSE 游标名称;
下面举个例子说明如何使用游标,我们通过游标查询表
test_table
里的第一条记录,以存储过程为例: ```sql创建一个存储过程,里面使用游标访问查询语句结果集的第一条记录
CREATE PROCEDURE cursor_procedure() BEGIN DECLARE id_temp INT; DECLARE name_temp VARCHAR(30); DECLARE cursor_test CURSOR FOR SELECT * FROM test_table;
OPEN cursor_test; FETCH cursor_test INTO id_temp, name_temp; SELECT id_temp, name_temp; CLOSE cursor_test; END;
调用存储过程
CALL cursor_procedure();
**注意:**
- 创建游标的语句,要放在声明局部变量的语句后面。
<a name="jXJTy"></a>
# 2、使用游标遍历结果集
<a name="bELXD"></a>
## 2.1 普通遍历
使用游标遍历结果集时,需要事先通过`COUNT(*)`获得结果集的总长度。<br />**举例:**
```sql
CREATE PROCEDURE cursor_procedure()
BEGIN
DECLARE id_temp INT;
DECLARE name_temp VARCHAR(30);
DECLARE cursor_count INT DEFAULT 0;
DECLARE i INT;
# 创建游标
DECLARE cursor_test CURSOR FOR SELECT * FROM test_table;
# 获得test_table表中记录的总数目
SELECT COUNT(*) FROM test_table INTO cursor_count;
OPEN cursor_test;
WHILE i < cursor_count DO
FETCH cursor_test INTO id_temp, name_temp;
SELECT id_temp, name_temp;
SET i = i + 1;
END WHILE;
CLOSE cursor_test;
END;
# 调用存储过程
CALL cursor_procedure();
2.2 遍历结束时执行策略
其实在FETCH
语句获取不到记录的时候会触发一个事件,从而我们可以得知所有的记录都被获取过了,然后我们就可以去主动的停止循环。MySQL
中响应这个事件的语句如下:
DECLARE CONTINUE HANDLER FOR NOT FOUND 处理语句;
只要我们在存储过程中写了这个语句,那么在FETCH
语句获取不到记录的时候,服务器就会执行我们填写的处理语句。
重新书写2.1中的遍历语句:
CREATE PROCEDURE cursor_procedure()
BEGIN
DECLARE id_temp INT;
DECLARE name_temp VARCHAR(30);
DECLARE leave_flag INT DEFAULT 0;
# 创建游标
DECLARE cursor_test CURSOR FOR SELECT * FROM test_table;
# 创建遍历结束的标志位
DECLARE CONTINUE HANDLER FOR NOT FOUND SET leave_flag = 1;
OPEN cursor_test;
leave_flag: LOOP
FETCH cursor_test INTO id_temp, name_temp;
IF leave_flag = 1 THEN
LEAVE leave_flag;
END IF;
SELECT id_temp, name_temp;
END LOOP leave_flag;
CLOSE cursor_test;
END;
# 调用存储过程
CALL cursor_procedure();