虽然通过WHERE或者HVAING,或者是限定返回记录的关键字LIMIT返回一条记录,但是却无法像是JAVA中对对集合操作那样,可以定义一个集合存储数据的位置或者随意定义集合中的任意一个位置,然后对记录的数据进行处理。
而MYSQL为了解决这个问题,就使用到了游标,这样提供了一个灵活的操作方式,让用户可以对记过集中的每一个记录进行定位,然后对指定的记录中的数据进行操作。因此游标让SQL这种面向集合的语言拥有了面向过程的开发能力。
游标是一种临时的数据库对象,可以指向存储再数据库表中的数据行,通过操作游标来对数据行进行操作。
使用游标步骤
游标的必须声明在处理程序之前,并且变量和条件必须在声明游标或处理程序之前声明。
1:声明游标
在MYSQL中格式如下:
DECLARE 游标名 CURSOR FOR SELECT得到集合
这样声明适用于:MYSQL, SQL Server ,MariaDB等数据库。
在Oracle中如下:
DECLARE 游标名 CURSOR IS SELECT得到集合
这样声明适用于:Oracle , PostgreSQL 等数据库。
2: 打开游标
打开游标的格式如下:
OPEN 游标名
定义游标后,如果要使用游标,就必须打开游标,打开游标的时候SELECT语句的查询结果集就会送到游标工作区,这样为后面逐行读取结果集的做准备。
3:使用游标
格式如下:
FETCH 游标名 INTO var_name[,var_name1,.....]
通过FETCH来按行读取游标中的数据,并且将行中数据保存到var_name中,游标指向到下一行。如果SELECG语句中的字段列有多个,就在INTO后面赋值多个变量名即可。
注意:var_name 必须在声明游标之前定义好。同时要注意查询结果集中的字段数必须要和INTO后面的变量数一样多,
否则在存储过程就会报错。
游标关闭之后,就不能再检索查询结果中的数据行,如果需要检索只能再次打开游标。
4:关闭游标
格式如下:
CLOSE 游标名
有打开就自然有关闭,其实打开光标的时候就会占用资源。如果不及时关闭的话,游标会一直保持到存储过程结束
,影响系统的运行效率,所以需要手动关闭游标的操作,会释放游标占用的系统资源。
演示
使用的表:
DELIMITER $
CREATE PROCEDURE cursor_test(OUT count_num INT)
BEGIN
DECLARE total_sal DOUBLE;# 薪资共有多少
DECLARE sal_sum DOUBLE DEFAULT 0;# 累计前几位薪资和
DECLARE sal_emp DOUBLE;# 单个员工的工资
DECLARE cursor_name CURSOR FOR
SELECT sal FROM emp ORDER BY sal DESC; #这个放在声明变量的后面,如果将SET count_num=0;放在声明游标前面运行存储过程就会报错;
SET count_num=0;
SELECT SUM(sal) INTO total_sal FROM emp ;
OPEN cursor_name;
REPEAT # 考虑到有可能第一位的收入有可能就占了40%所以至少需要执行一次
FETCH cursor_name INTO sal_emp; # 这里记得带; 不然会报错
SET count_num=count_num+1;
SET sal_sum=sal_sum+sal_emp;
UNTIL sal_sum/total_sal>0.4
END REPEAT ;
CLOSE cursor_name;
END $
DELIMITER ;
#调用
SET @count_num=0;
CALL cursor_test(@count_num);
SELECT @count_num;