MySQL 游标
概述
本章节介绍使用游标来批量进行表操作,包括批量添加索引、批量添加字段等。如果对存储过程、变量定义、预处理还不是很熟悉先阅读我前面写过的关于这三个概念的文章,只有先了解了这三个概念才能更好的理解这篇文章。
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
正文
光标声明
声明光标
DECLARE cursor_name CURSOR FOR select_statement
这个语句声明一个光标。也可以在子程序中定义多个光标,但是一个块中的每一个光标必须有唯一的名字。
注意:SELECT语句不能有INTO子句。
打开光标
OPEN cursor_name
这个语句打开先前声明的光标。
前进光标
FETCH cursor_name INTO var_name [, var_name] ...
这个语句用指定的打开光标读取下一行(如果有下一行的话),并且前进光标指针。
关闭光标
CLOSE cursor_name
这个语句关闭先前打开的光标。
批量添加索引
共享一个批量添加索引的游标,当一个库中有上百张表结构一样但是名称不一样的表,这个时候批量操作就变得简单了。
#删除创建存储过程
DROP PROCEDURE IF EXISTS FountTable;
DELIMITER $$
CREATE PROCEDURE FountTable()
BEGIN
DECLARE TableName varchar(64);
#声明游标
DECLARE cur_FountTable CURSOR FOR SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='front' AND TABLE_NAME LIKE 'student%';
DECLARE EXIT HANDLER FOR not found CLOSE cur_FountTable;
#打开游标
OPEN cur_FountTable;
REPEAT
FETCH cur_FountTable INTO TableName;
#定义预处理
SET @SQLSTR1 = CONCAT('create index Flag on ','`',TableName,'`',' (Flag); ');
SET @SQLSTR2 = CONCAT('create index State on ','`',TableName,'`',' (State); ');
SET @SQLSTR3 = CONCAT('create index upload on ','`',TableName,'`',' (upload); ');
SET @SQLSTR4 = CONCAT('create index ccFlag on ','`',TableName,'`',' (lockFlag); ');
SET @SQLSTR5 = CONCAT('create index comes on ','`',TableName,'`',' (comes); ');
###SET @SQLSTR=CONCAT(@SQLSTR1,@SQLSTR2,@SQLSTR3,@SQLSTR4,@SQLSTR5 );
PREPARE STMT1 FROM @SQLSTR1;
PREPARE STMT2 FROM @SQLSTR2;
PREPARE STMT3 FROM @SQLSTR3;
PREPARE STMT4 FROM @SQLSTR4;
PREPARE STMT5 FROM @SQLSTR5;
EXECUTE STMT1;
EXECUTE STMT2;
EXECUTE STMT3;
EXECUTE STMT4;
EXECUTE STMT5;
DEALLOCATE PREPARE STMT1;
DEALLOCATE PREPARE STMT2;
DEALLOCATE PREPARE STMT3;
DEALLOCATE PREPARE STMT4;
DEALLOCATE PREPARE STMT5;
# SELECT @SQLSTR; UNTIL 0 END REPEAT;
#关闭游标
CLOSE cur_FountTable; END $$
DELIMITER ; CALL FountTable();
这里有几个细节:
- 在声明游标的时候记得修改自己需要查询的条件
- 在预处理这里也需要改成对应的字段
- 在定义条件变量的时候这里我使用的是EXIT就是遇到错误就中断,当然也可以使用CONTINUE 。
游标嵌套授权
DROP PROCEDURE IF EXISTS pro_grant_pri;
DELIMITER $$
CREATE PROCEDURE pro_grant_pri()
BEGIN
DECLARE cur1_username varchar(128);
DECLARE cur2_dbname varchar(128);
DECLARE done int; DECLARE cur1 CURSOR FOR SELECT username FROM testuser;
DECLARE cur2 CURSOR FOR SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME like 'test%'; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; OPEN cur1;
out_loop:LOOP
FETCH cur1 INTO cur1_username;
IF done = 1 THEN
LEAVE out_loop;
END IF; OPEN cur2;
inner_loop:LOOP
FETCH cur2 INTO cur2_dbname;
IF done = 1 THEN
LEAVE inner_loop;
END IF; SET @SQLSTR1 = CONCAT('grant select,insert,delete,update on ',cur2_dbname,'.*',' to ','''',cur1_username,'''','@','''%'';') ;
PREPARE STMT1 FROM @SQLSTR1;
EXECUTE STMT1;
DEALLOCATE PREPARE STMT1; end LOOP inner_loop;
CLOSE cur2;
SET done=0;
END LOOP out_loop;
CLOSE cur1; END $$
DELIMITER ;
注意:
1.由于mysql在存储过程当中无法将查询出来的变量名直接作为表名来用,所以这里要用到动态拼接SQL的方法,但是通常的SET CONCAT的方法并不管用,所以这里就使用了PREPARE来进行预编译。
2.在定义游标之前所以的定义都只能通过decalre定义,不能使用SET定义!!!!!!
3.定义的变量名不能和表返回的字段名相同,否则接收的值为空。
总结
批量处理虽然有时候能提高工作的效率,但是带来的潜在危险也是挺大了,所以在执行之前必须要非常有把握你执行的语句对数据的影响,否则在生成环境就非常危险了。
|
备注: 作者:pursuer.chen 博客:http://www.cnblogs.com/chenmh 本站点所有随笔都是原创,欢迎大家转载;但转载时必须注明文章来源,且在文章开头明显处给明链接。 《欢迎交流讨论》 |
MySQL 游标的更多相关文章
- SqlServer和MySQL游标学习
一 sqlserver游标使用 /*** 游标的使用 讲了这个多游标的优点,现在我们就亲自来揭开游标的神秘的面纱. 使用游标的顺序: 声名游标.打开游标.读取数据.关闭游标.删除游标. 1.3.1 ...
- MySQL游标操作指南
本篇文章是对MySQL游标的具体使用进行了详细的分析介绍,需要的朋友参考下 测试表 level 代码如下: create table test.level (name varchar(20)); ...
- 个人笔记mysql游标
经过测试,mysql游标是无法读取自定义函数计算的结构,mysql自带的函数计算值是可以读取的.
- MySQL游标的简单实践
Q:为什么要使用游标? A: 在存储过程(或函数)中,如果某条select语句返回的结果集中只有1行,可以使用select into语句(上几篇博客有介绍到用法)来得到该行进行处理:如果结果集中有多行 ...
- mysql 游标 demo
一.MySQL游标的概念 1.游标介绍 MySQL的游标(cursor)是一个重要的概念,通过查找资料与自己的理解,主要得出以下几点关于自己的理解. 有数据缓冲的思想:游标的设计是一种数据缓冲区的思想 ...
- [转]MySQL游标的使用
转自:http://www.cnblogs.com/sk-net/archive/2011/09/07/2170224.html 以下的文章主要介绍的是MySQL游标的使用笔记,其可以用在存储过程的S ...
- Mysql 游标初识
MySql 游标初识 认识 游标(cursor), 按字面意思可理解为, 游动的标识, 或者叫做"光标", 这样更容易理解. 就好比现有一张表存储了n行记录, 然后我想每次取出一行 ...
- Mysql游标的简明写法
-- cursor 游标/*declare 声明; declare 游标名 cursor for select_statement;open 找开; open 游标名fetch 取值; fetch 游 ...
- MySQL游标循环取出空值的BUG
早上同事要我写个MySQL去除重复数据的SQL,想起来上次写过一篇MySQL去除重复数据的博客,使用导入导出加唯一索引实现的,但是那种方式对业务影响较大,所以重新写一个存储过程来删重复数据,这一写就写 ...
随机推荐
- C#: using JsonReader avoid Deserialize Json to dynamic
namespace Test { using Microshaoft; using Test.Models; using Newtonsoft.Json; using System; using Sy ...
- 【积累篇:他山之石,把玉攻】解决XP 系统 .Net Framework 4安装时出现严重错误 (0x80070643)
第一步: 1.开始——运行——输入cmd——回车——在打开的窗口中输入net stop WuAuServ 2.开始——运行——输入%windir% 3.在打开的 的窗口中有个文件夹叫SoftwareD ...
- Codeforces Round #379 (Div. 2)
A ~~ B ~~ C 对于第二种方法,我们可以任取一个换c[i]个potions,花费d[i]:或者是不取,我的做法就是枚举这些情况,得到剩余的s,再尽量优的获取小的a[i]: 枚举+二分 #inc ...
- Java 之 GUI
1.SWT: a.组成:①java.awt包:工具类--颜色.字体类等 ②javax.swing包:容器类 与 组件 (java.awt包中容器类与组件的升级版,以J打头) b.总结:SWT = Sw ...
- 加密狗的管理层API(C#代码)
using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServi ...
- UVA 11168 Airport(凸包+直线方程)
题意:给你n[1,10000]个点,求出一条直线,让所有的点都在都在直线的一侧并且到直线的距离总和最小,输出最小平均值(最小值除以点数) 题解:根据题意可以知道任意角度画一条直线(所有点都在一边),然 ...
- Qt中暂停线程的执行
在线程中定义一个信号量 QMutex pause; 把run()函数中循环执行的部分用信号量pause锁住: void run() { while(1) { pause.lock(); //循环执行的 ...
- Web API返回JSON数据
对Web API新手来说,不要忽略了ApiController 在web API中,方法的返回值如果是实体的话实际上是自动返回JSON数据的例如: 他的返回值就是这样的: { "Conten ...
- Basic Calculator II
Implement a basic calculator to evaluate a simple expression string. The expression string contains ...
- LINUX下编译安装PHP各种报错大集合
本文为大家整理汇总了一些linux下编译安装php各种报错大集合 ,感兴趣的同学参考下. nginx1.6.2-mysql5.5.32二进制,php安装报错解决: 123456 [root@clien ...