游标

什么是游标

在 SQL 中,游标是一种临时的数据库对象,可以指向存储在数据库表中的数据行指针。这里游标充当了指针的作用,我们可以通过操作游标来对数据行进行操作。

MySQL 中游标可以在存储过程和函数中使用。

使用游标步骤

游标必须在声明处理程序之前被声明,并且变量和条件还必须在声明游标或处理程序之前被声明。

如果我们想要使用游标,一般需要经历四个步骤。不同的 DBMS 中,使用游标的语法可能略有不同。

第一步,声明游标

#  MySQL,SQL Server,DB2 和 MariaDB 用法
DECLARE cursor_name CURSOR FOR select_statement;
 
# Oracle 或者 PostgreSQL 用法
# DECLARE cursor_name CURSOR IS select_statement;
DECLARE cur_emp CURSOR FOR SELECT employee_id,salary FROM employees;

第二步,打开游标

OPEN cursor_name;

第三步,使用游标(从游标中取得数据)

FETCH cursor_name INTO var_name [, var_name] ...
# 读取数据,并传入变量中,然后游标移动到下一个
FETCH cur_emp INTO emp_id, emp_sal;

注意:游标的查询结果集中的字段数,必须跟 INTO 后面的变量数一致,否则,在存储过程执行的时候,MySQL 会提示错误。

第四步,关闭游标

CLOSE cursor_name;

当我们使用完游标后需要关闭掉该游标。因为游标会占用系统资源,如果不及时关闭,游标会一直保持到存储过程结束,影响系统运行的效率。

举例

DELIMITER //
 
CREATE PROCEDURE get_count_by_limit_total_salary(IN limit_total_salary DOUBLE,OUT total_count INT)
 
BEGIN
	DECLARE sum_salary DOUBLE DEFAULT 0;  #记录累加的总工资
	DECLARE cursor_salary DOUBLE DEFAULT 0; #记录某一个工资值
	DECLARE emp_count INT DEFAULT 0; #记录循环个数
	#定义游标
	DECLARE emp_cursor CURSOR FOR SELECT salary FROM employees ORDER BY salary DESC;
	#打开游标
	OPEN emp_cursor;
 
	REPEAT
		#使用游标(从游标中获取数据)
		FETCH emp_cursor INTO cursor_salary;
 
		SET sum_salary = sum_salary + cursor_salary;
		SET emp_count = emp_count + 1;
 
		UNTIL sum_salary >= limit_total_salary
	END REPEAT;
 
	SET total_count = emp_count;
	#关闭游标
	CLOSE emp_cursor;
 
END //
 
DELIMITER ;

小结

游标是 MySQL 的一个重要的功能,为逐条读取结果集中的数据,提供了完美的解决方案。跟在应用层面实现相同的功能相比,游标可以在存储程序中使用,效率高,程序也更加简洁。

但同时也会带来一些性能问题,比如在使用游标的过程中,会对数据行进行加锁,这样在业务并发量大的时候,不仅会影响业务之间的效率,还会消耗系统资源,造成内存不足,这是因为游标是在内存中进行的处理。

建议:养成用完之后就关闭的习惯,这样才能提高系统的整体效率。