概述

本章节介绍使用游标来批量进行表操作,包括批量添加索引、批量添加字段等。如果对存储过程、变量定义、预处理还不是很熟悉先阅读我前面写过的关于这三个概念的文章,只有先了解了这三个概念才能更好的理解这篇文章。

MySQL变量和条件:http://www.cnblogs.com/chenmh/p/5203429.html

PREPARE 预处理语句:http://www.cnblogs.com/chenmh/articles/5308085.html

MySQL存储过程和函数:http://www.cnblogs.com/chenmh/p/5201473.html

正文

光标声明

声明光标

  1. DECLARE cursor_name CURSOR FOR select_statement

这个语句声明一个光标。也可以在子程序中定义多个光标,但是一个块中的每一个光标必须有唯一的名字。

注意:SELECT语句不能有INTO子句。

打开光标

  1. OPEN cursor_name

这个语句打开先前声明的光标。

前进光标

  1. FETCH cursor_name INTO var_name [, var_name] ...

这个语句用指定的打开光标读取下一行(如果有下一行的话),并且前进光标指针。

关闭光标

  1. CLOSE cursor_name

这个语句关闭先前打开的光标。

批量添加索引

共享一个批量添加索引的游标,当一个库中有上百张表结构一样但是名称不一样的表,这个时候批量操作就变得简单了。

  1. #删除创建存储过程
    DROP PROCEDURE IF EXISTS FountTable;
  2. DELIMITER $$
  3. CREATE PROCEDURE FountTable()
  4. BEGIN
  5. DECLARE TableName varchar(64);
    #声明游标
  6. DECLARE cur_FountTable CURSOR FOR SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='front' AND TABLE_NAME LIKE 'student%';
  7. DECLARE EXIT HANDLER FOR not found CLOSE cur_FountTable;
  8. #打开游标
  9. OPEN cur_FountTable;
  10. REPEAT
  11. FETCH cur_FountTable INTO TableName;
  12. #定义预处理
  13. SET @SQLSTR1 = CONCAT('create index Flag on ','`',TableName,'`',' (Flag); ');
  14. SET @SQLSTR2 = CONCAT('create index State on ','`',TableName,'`',' (State); ');
  15. SET @SQLSTR3 = CONCAT('create index upload on ','`',TableName,'`',' (upload); ');
  16. SET @SQLSTR4 = CONCAT('create index ccFlag on ','`',TableName,'`',' (lockFlag); ');
  17. SET @SQLSTR5 = CONCAT('create index comes on ','`',TableName,'`',' (comes); ');
  18. ###SET @SQLSTR=CONCAT(@SQLSTR1,@SQLSTR2,@SQLSTR3,@SQLSTR4,@SQLSTR5 );
  19. PREPARE STMT1 FROM @SQLSTR1;
  20. PREPARE STMT2 FROM @SQLSTR2;
  21. PREPARE STMT3 FROM @SQLSTR3;
  22. PREPARE STMT4 FROM @SQLSTR4;
  23. PREPARE STMT5 FROM @SQLSTR5;
  24. EXECUTE STMT1;
  25. EXECUTE STMT2;
  26. EXECUTE STMT3;
  27. EXECUTE STMT4;
  28. EXECUTE STMT5;
  29. DEALLOCATE PREPARE STMT1;
  30. DEALLOCATE PREPARE STMT2;
  31. DEALLOCATE PREPARE STMT3;
  32. DEALLOCATE PREPARE STMT4;
  33. DEALLOCATE PREPARE STMT5;
  34. # SELECT @SQLSTR;
  35.  
  36. UNTIL 0 END REPEAT;
  37. #关闭游标
  38. CLOSE cur_FountTable;
  39.  
  40. END $$
  41. DELIMITER ;
  42.  
  43. CALL FountTable();

这里有几个细节:

  • 在声明游标的时候记得修改自己需要查询的条件
  • 在预处理这里也需要改成对应的字段
  • 在定义条件变量的时候这里我使用的是EXIT就是遇到错误就中断,当然也可以使用CONTINUE 。

游标嵌套授权

  1. DROP PROCEDURE IF EXISTS pro_grant_pri;
  2. DELIMITER $$
  3. CREATE PROCEDURE pro_grant_pri()
  4. BEGIN
  5. DECLARE cur1_username varchar(128);
  6. DECLARE cur2_dbname varchar(128);
  7. DECLARE done int;
  8.  
  9. DECLARE cur1 CURSOR FOR SELECT username FROM testuser;
  10. DECLARE cur2 CURSOR FOR SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME like 'test%';
  11.  
  12. DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  13.  
  14. OPEN cur1;
  15. out_loop:LOOP
  16. FETCH cur1 INTO cur1_username;
  17. IF done = 1 THEN
  18. LEAVE out_loop;
  19. END IF;
  20.  
  21. OPEN cur2;
  22. inner_loop:LOOP
  23. FETCH cur2 INTO cur2_dbname;
  24. IF done = 1 THEN
  25. LEAVE inner_loop;
  26. END IF;
  27.  
  28. SET @SQLSTR1 = CONCAT('grant select,insert,delete,update on ',cur2_dbname,'.*',' to ','''',cur1_username,'''','@','''%'';') ;
  29. PREPARE STMT1 FROM @SQLSTR1;
  30. EXECUTE STMT1;
  31. DEALLOCATE PREPARE STMT1;
  32.  
  33. end LOOP inner_loop;
  34. CLOSE cur2;
  35. SET done=0;
  36. END LOOP out_loop;
  37. CLOSE cur1;
  38.  
  39. END $$
  40. DELIMITER ;

注意:

1.由于mysql在存储过程当中无法将查询出来的变量名直接作为表名来用,所以这里要用到动态拼接SQL的方法,但是通常的SET CONCAT的方法并不管用,所以这里就使用了PREPARE来进行预编译。

2.在定义游标之前所以的定义都只能通过decalre定义,不能使用SET定义!!!!!!

3.定义的变量名不能和表返回的字段名相同,否则接收的值为空。

总结

批量处理虽然有时候能提高工作的效率,但是带来的潜在危险也是挺大了,所以在执行之前必须要非常有把握你执行的语句对数据的影响,否则在生成环境就非常危险了。

备注:

作者:pursuer.chen

博客:http://www.cnblogs.com/chenmh

本站点所有随笔都是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接。

《欢迎交流讨论》

MySQL 游标的更多相关文章

  1. SqlServer和MySQL游标学习

    一 sqlserver游标使用 /*** 游标的使用  讲了这个多游标的优点,现在我们就亲自来揭开游标的神秘的面纱.  使用游标的顺序: 声名游标.打开游标.读取数据.关闭游标.删除游标. 1.3.1 ...

  2. MySQL游标操作指南

    本篇文章是对MySQL游标的具体使用进行了详细的分析介绍,需要的朋友参考下   测试表 level  代码如下: create table test.level (name varchar(20)); ...

  3. 个人笔记mysql游标

    经过测试,mysql游标是无法读取自定义函数计算的结构,mysql自带的函数计算值是可以读取的.

  4. MySQL游标的简单实践

    Q:为什么要使用游标? A: 在存储过程(或函数)中,如果某条select语句返回的结果集中只有1行,可以使用select into语句(上几篇博客有介绍到用法)来得到该行进行处理:如果结果集中有多行 ...

  5. mysql 游标 demo

    一.MySQL游标的概念 1.游标介绍 MySQL的游标(cursor)是一个重要的概念,通过查找资料与自己的理解,主要得出以下几点关于自己的理解. 有数据缓冲的思想:游标的设计是一种数据缓冲区的思想 ...

  6. [转]MySQL游标的使用

    转自:http://www.cnblogs.com/sk-net/archive/2011/09/07/2170224.html 以下的文章主要介绍的是MySQL游标的使用笔记,其可以用在存储过程的S ...

  7. Mysql 游标初识

    MySql 游标初识 认识 游标(cursor), 按字面意思可理解为, 游动的标识, 或者叫做"光标", 这样更容易理解. 就好比现有一张表存储了n行记录, 然后我想每次取出一行 ...

  8. Mysql游标的简明写法

    -- cursor 游标/*declare 声明; declare 游标名 cursor for select_statement;open 找开; open 游标名fetch 取值; fetch 游 ...

  9. MySQL游标循环取出空值的BUG

    早上同事要我写个MySQL去除重复数据的SQL,想起来上次写过一篇MySQL去除重复数据的博客,使用导入导出加唯一索引实现的,但是那种方式对业务影响较大,所以重新写一个存储过程来删重复数据,这一写就写 ...

随机推荐

  1. SPFA

    SPFA算法用来求单源最短路.可以处理任何有解的情况. 先建一个数组\(dist_x = 起点到x的最短路长度\),当\(x=起点\)时为0,当x和起点不通时为INF(本题中为\(2^31-1\)). ...

  2. 自用VS Code 上的Markdown 编辑器css

    目标效果如下: 主题使用:Markdown Yellow 主题[https://marketplace.visualstudio.com/items?itemName=ms-vscode.Theme- ...

  3. 《DSP using MATLAB》示例Example5.23

    代码: conv_time = zeros(1,150); fft_time = zeros(1, 150); % % Nmax = 2048; for L = 1:150 tc = 0; tf = ...

  4. (转) Android开发性能优化简介

    作者:贺小令 随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序.以上理由,足以 ...

  5. LINUX 常用命令 ps 详解

    ps常用命令 ps -u ceshi 查看特定用户(ceshi)进程的情况 ps aux | grep nginx 查找nginx的进程 pa -ef | grep nginx 查找nginx的进程 ...

  6. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  7. App Framework $.ui.loadContent 参数解释

    在使用 app Framework 的 $.ui.loadContent(target,newTab,goBack,transition);时 对 newTab goback两个参数一直不得其解.通过 ...

  8. HDU 1907 Nim博弈变形

    1.HDU 1907 2.题意:n堆糖,两人轮流,每次从任意一堆中至少取一个,最后取光者输. 3.总结:有点变形的Nim,还是不太明白,盗用一下学长的分析吧 传送门 分析:经典的Nim博弈的一点变形. ...

  9. web存储

    1. cookie: 如果想将cookie取到,可以通过document.cookie;取到的是所有的cookie数据 他是一直保存在网页中的:他有一个时间的限制,如果时间过期,则删除 写入:docu ...

  10. 弹出popwindow 背景变暗

    先看下效果图吧 代码如下 package com.example.administrator.popwindowdemo.view; import android.app.Activity; impo ...