重学MYSQL之使用游标

数据库 2020-09-12 1182

1.游标

SQL检索操作返回的一组称为结果集(SQL查询所检索出的结果)的行,这组返回的行都是与SQL语句相匹配的行(0行或多行)。现在,我希望得到第一行,最后一行或者前10行,这时,简单的SELECT语句没有办法得到,而这恰恰是游标的用途所在。

游标(cursor)是一个存储在DB服务器上的数据库查询,它不是SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。

不同的数据库支持不同的游标选项和特性。常见的一些选项和特性如下:

  • 能够标记游标为只读,使数据能够读取,但不能更新和删除
  • 能控制可以执行的定向操作(向前,向后,第一,最后,绝对位置,相对位置等)
  • 能标记某些列为可编辑的,某些列为不可编辑
  • 规定范围,使游标对创建它的特定请求(如存储过程)或对所有请求可访问
  • 指示数据库对检索出的数据(而不是指出表中的活动数据)进行复制,使数据在游标打开和访问期间不变化

说明:Access不支持游标

游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览和做出更改。

说明:在基于WEB的应用中,不使用游标 

2.使用游标

使用游标的步骤:

  1. 在使用游标前,必须定义它,这个过程实际上没有检索数据,它只是定义要使用的SELECT语句和游标选项
  2. 一旦定义,就必须打开游标以供使用。这个过程用前面定义的SELECT语句把数据实际检索出来
  3. 对于填有数据的游标,根据需要取出(检索)各行
  4. 在结束游标使用后,必须关闭游标,可能的话,释放游标。

声明游标后,可根据需要频繁打开和关闭游标。在游标打开时,可根据需要频繁的进行取操作。

2.1 创建游标

使用DECLARE语句创建游标,这条语句在不同的数据库中有所不同。 DECLARE命名游标,并定义相应的SELECT语句,根据需要带WHERE和其他子句

下面是创建此游标的DB2、MariaDB和SQL Server版本

DECLARE @CustCursor CURSOR FOR SELECT * FROM goods_goods WHERE shop_price > 50;

MySQL数据库的游标只能在存储过程中使用

BEGIN
	DECLARE goods CURSOR FOR SELECT * FROM goods_goods WHERE shop_price > 50; -- 定义游标
	OPEN goods; -- 打开游标
    CLOSE goods; -- 关闭游标
END

Oracle数据库使用游标

DECLARE CURSOR goods IS SELECT * FROM goods_goods WHERE shop_price > 50;

2.2 使用游标

使用OPEN CURSOR语句打开游标

OPEN CURSOR goods;

在处理OPEN CURSOR 语句时,执行查询,存储检索出的数据以供浏览和滚动。

现在可以使用FETCH语句访问游标数据。FETCH指出要检索那些行,从何处检索它们以及将它们放于何处。

下列例子使用MySQL为例子,检索一行数据:

DROP PROCEDURE IF EXISTS `GoodCount`;

CREATE DEFINER = `root`@`localhost` PROCEDURE `GoodCount`()
BEGIN
	  -- CREATE PROCEDURE Good_Count() -- 创建存储过程 Good_Count
		DECLARE price int; -- 定义本地变量o
		DECLARE goods CURSOR FOR SELECT shop_price FROM goods_goods WHERE shop_price > 50; -- 定义游标
		OPEN goods; -- 打开游标
		FETCH goods INTO price; -- 获取结果
    SELECT price; -- 这里是为了显示获取结果
		-- 如果出现1328 - Incorrect number of FETCH variables,游标select的字段数需要与fetch into的变量数一致
    CLOSE goods; -- 关闭游标
END;

效果:

使用循环遍历出所有数据保存到另一个表

DROP PROCEDURE IF EXISTS `GoodCount`;

CREATE DEFINER = `root`@`localhost` PROCEDURE `GoodCount`()
BEGIN
	  -- CREATE PROCEDURE Good_Count() -- 创建存储过程 Good_Count
		DECLARE price int; -- 定义本地变量o
    -- 创建结束标志变量  
    declare done int default false;
		DECLARE goods CURSOR FOR SELECT shop_price FROM goods_goods WHERE shop_price > 50; -- 定义游标
		-- 指定游标循环结束时的返回值  
    declare continue HANDLER for not found set done = true;
		OPEN goods; -- 打开游标
		REPEAT
			FETCH FROM goods INTO price; -- 获取结果
			INSERT INTO table VALUES(...)
		UNTIL done END REPEAT;
		-- 如果出现1328 - Incorrect number of FETCH variables,游标select的字段数需要与fetch into的变量数一致
    CLOSE goods; -- 关闭游标
END;

关于mysql触发器,可以参考https://www.cnblogs.com/progor/p/8875100.html

标签:数据库

文章评论

评论列表

已有0条评论