zoukankan      html  css  js  c++  java
  • mysql学习笔记-游标

    1、游标的基本概念

    有数据缓冲的思想:游标的设计是一种数据缓冲区的思想,用来存放SQL语句执行的结果

    先有数据基础:游标是在先从数据表中检索出数据之后才能继续灵活操作的技术。

    类似于指针:游标类似于指向数据结构堆栈中的指针,用来pop出所指向的数据,并且只能每次取一个。

    如果你前面看过mysql函数,会发现无法使用返回多行结果的语句。但如果你又确实想要使用时,就需要使用到游标,游标可以帮你选择出某个结果(这样就可以做到返回单个结果)。

    另外,使用游标也可以轻易的取出在检索出来的行中前进或后退一行或多行的结果

    游标可以遍历返回的多行结果

    • Mysql中游标只适用于存储过程以及函数。

    2、游标的使用

    游标的使用一般分为5个步骤,主要是:定义游标->打开游标->使用游标->关闭游标->释放游标

    需要强调的是,游标必须在定义处理程序之前被定义,但变量必须在定义游标之前被定义,顺序就是变量定义-游标定义-处理程序

    前提:

    -- 创建两个表,表没有主键会一直循环
    CREATE TABLE class(id int(5) PRIMARY KEY,name VARCHAR(10));
    CREATE TABLE class2(id int(5) PRIMARY KEY,name VARCHAR(10));
    
    -- class里插入数据
    INSERT INTO class(`id`, `name`) VALUES ('1', 'ceshi');
    SELECT * FROM class ;
    
    -- class表里数据删除或者删除表
    DELETE FROM class2;
    DROP TABLE class2;
    create procedure p2()
    begin
        declare id int;
        declare name varchar(15);
        -- 声明游标
        declare mc cursor for select * from class;
        -- 打开游标
        open mc;
        -- 获取结果
        loop  -- 循环,将表的内容都转移到class2中
        fetch mc into id,name;
        -- 这里是为了显示获取结果
        insert into class2 values(id,name);
        -- 关闭游标
        end loop;
        close mc;
        
    end;

    上述代码报错

     

    表class2有主键,不断循环的话,始终会达到表的末尾,到了末尾就无法继续fetch,一般来说都要避免报错,到了末尾前会有一个mysql定义的

    delimiter //
    create procedure p8()
    begin
        declare id int;
        declare name varchar(15);
        declare flag int default 0;
        -- 声明游标
        declare mc cursor for select * from class;
        declare continue handler for not found set flag = 1;
        -- 打开游标
        open mc;
        -- 获取结果
        l2:loop 
        
        fetch mc into id,name;
        if flag=1 then -- 当无法fetch会触发handler continue
            leave l2;
        end if;
        -- 这里是为了显示获取结果
        insert into class2 values(id,name);
        -- 关闭游标
        end loop;
        close mc;
        
    end;
    
    //
    delimiter ;
    CALL p8();
    CREATE TABLE `emp1` (
      `empno` int(10) NOT NULL,
      `ename` varchar(10) COLLATE utf8_bin DEFAULT NULL,
      `deptno` int(5) DEFAULT NULL,
      `sal` int(10) DEFAULT NULL,
      PRIMARY KEY (`empno`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
    
    delimiter //
    CREATE PROCEDURE test_cfl()
    BEGIN
        DECLARE empno INT;
        DECLARE ename VARCHAR(15);-- 带字节长度
        DECLARE deptno INT; 
        DECLARE sal BIGINT;
        DECLARE flag INT DEFAULT 0;
        -- 游标定义
        DECLARE     cr_cfl CURSOR FOR SELECT * FROM emp;
        -- 异常值设置
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag = 1;
        
        -- 打开游标
        OPEN cr_cfl    ;
        -- 循环设置
        loop1:LOOP
        -- 获取游标值
        FETCH cr_cfl INTO empno,ename,deptno,sal;
        -- 无法获取时退出
        IF flag=1 THEN 
            LEAVE loop1;
        END IF;
        -- 获取的值插入另外一张表
        INSERT INTO emp1 VALUES(empno,ename,deptno,sal);
        END LOOP;
        -- 关闭游标
        CLOSE cr_cfl;
    END;
    //
    delimiter ;
    CALL test_cfl();
    SELECT * FROM emp1;
  • 相关阅读:
    software系列:Tableau10.5安装教程(破解版)
    技巧系列:Excel打印技巧
    Android 3.0 访问WebService 出现 android.os.NetworkOnMainThreadException异常
    Android各种布局
    服务器访问本地磁盘
    Android手机客户端访问.NET服务器端的方法(1)
    flex webservice
    android学习之 intent 实例
    Android手机客户端访问.NET服务器端的方法(2)
    一篇不错的讲解Java异常的文章(转载)感觉很不错,读了以后很有启发
  • 原文地址:https://www.cnblogs.com/shishibuwan/p/10972655.html
Copyright © 2011-2022 走看看