第25课:会跳动的游标

本节要点

游标简介
游标的使用步骤
一个游标使用的示例
游标的优缺点

游标简介

先来看下面一个SQL:

UPDATE student SET age = age + 1;

执行这个SQL时,实际上数据库是将students表中所有记录的age字段加1。也就是说,数据库将students表中所有学生这个集合中的年龄全部加了1岁。

可有时候,我们针对students表中所有学生这个集合中的不同学生,可能有不同的操作。比如说,一年级一班的同学,每人加1岁;如果性别为女生或姓张的同学,每人加2岁。这样的逻辑,使用SQL语句来写,可能也能写。但SQL稍显复杂。

上面的场景还好。假如说,有更复杂的需求,使用单个SQL语句来编写可能就比较复杂了,而且要求我们对数据库中的每一行,都做相应的特殊处理,这样实现起来就比较难。

实际上,SQL语言提供了游标的功能,让我们能依次处理表中的每条记录。

游标类似于指针,从集合中依次提取单条记录,直至提取完最后一条,而且这个指针,每一次循环只指向一个单行。

这就给了我们针对表中每一行实现特有的逻辑的方法。

我们可以在存储过程、函数、触发器中使用游标。所以,游标的使用场景还是挺广的。

游标的使用步骤

在使用游标时,一般会经过下面四个步骤:

第一步:定义游标

DECLARE 游标名称 CURSOR FOR SELECT子句;

第二步:打开游标

OPEN 游标名称

第三步:使用游标

FETCH 游标名称 INTO 变量名1,变量名2,变量名3[,…]

第四步:关闭游标

CLOSE 游标名称

一个游标使用的示例

下面这个例子,从student表中,将成绩在90分以上的学生编号和学生姓名查询出来并返回,并没有做其他更复杂的操作。

实际上,我们WHILE循环的内部,针对每一条记录,完成需要的复杂操作。

这里只是举个例子,来说明游标是如何使用的:

CREATE PROCEDURE cursor_student()
BEGIN
    DECLARE v_student_id varchar(50);
    DECLARE v_student_name varchar(100);

    DECLARE done INT DEFAULT false;
    DECLARE mycursor CURSOR FOR SELECT student_id,student_name FROM student WHERE score >= 90;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;

    OPEN mycursor;

    FETCH mycursor INTO v_student_id,v_student_name;

    WHILE(NOT done)
    DO
        SELECT v_student_id,v_student_name;

        FETCH mycursor INTO v_student_id,v_student_name;
    END WHILE;

    CLOSE mycursor;
END;

游标的优缺点

当然了,游标也有它自己的优缺点。对于表的操作,它提供了一种除集合操作外的行操作方式。这一点在逻辑比较复杂的时候,非常有用。

但因为游标是对表中每一行单独做操作,所以在数据量比较大的时候,可能会造成内存不足,而且很多时候,性能比较差。

一般来说,我们不建议使用循环次数在1万以上的游标操作。对于循环次数太多的游标操作,建议将业务需求转换为多个集合操作来实现。

课后习题:

1、对于第6课课后习题中的论坛注册用户表、第15课课后习题中的文章表、用户访问的文章记录表,请编写SQL完成以下查询。

(1)、使用游标实现注册用户表中用户积分的奖励。

论坛准备进行一次积分奖励活动,对于最近30天有登录的用户,奖励1000分;最近90天有登录的用户,奖励500分,最近180天有登录的用户,奖励200分,最近365天有登录的用户,奖励100分,其他用户不奖励。

【版权说明:仅允许非商业转载且请注明出处:Mac私塾 网址:http://macsishu.com】

发表评论

邮箱地址不会被公开。

Captcha Code