需求:

有三张表:Player、Consumption、Consumption_other。Player表中记录用户信息(playerid、origin等字段),Consumption和Consumption_other记录用户的消费信息。现需要根据Player表中的origin字段,分别向Consumption和Consumption_other表中插入一条消费记录。规定:Player表中origin=0的,将信息插入到Consumption表中;Player表中origin不为0的,将信息插入到Consumption_other表中。

方法:

使用MySQL的存储过程和游标实现:

mysql> DELIMITER //
mysql> CREATE PROCEDURE `add_consumption`()-> BEGIN->   -- 定义需要接收游标数据的变量->   DECLARE id int(11);->   DECLARE origin int(11);->   -- 定义遍历数据结束标志->   DECLARE done BOOLEAN DEFAULT 0;->   -- 定义游标->   DECLARE cur CURSOR FOR SELECT->     player.playerid as id,->     player.origin as origin->   FROM player;->   -- 将结束标志绑定到游标->   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;->   -- 打开游标->   OPEN cur;->     -- 关闭事务自动提交->     SET autocommit=0;->     -- 开始循环->     read_loop:LOOP->       -- 提取游标中的数据->       FETCH cur INTO id,origin;->       -- 声明何时结束循环->       IF done THEN->         LEAVE read_loop;->       END IF;->       -- 循环时的事件->       IF origin=0->       THEN->         INSERT INTO consumption VALUES (0,1525467600);->       ELSE->         INSERT INTO consumption_other VALUES(0,1525467600);->       END IF;->     END LOOP;->     commit;->     -- 关闭游标->   CLOSE cur;-> END-> //
mysql> DELIMITER ;
mysql> call add_consumption();

存储过程相关:

1、创建存储过程:

格式:

CREATE PROCEDURE 过程名([参数])过程体

例子:

mysql> DELIMITER //
mysql> CREATE PROCEDURE `originplayer`(->     IN ori int(11),->     OUT total int(11)-> )-> BEGIN->   select count(*) from player where origin=ori into total;-> END//
mysql> DELIMITER ;
mysql> call originplayer(0, @total);
mysql> select @total;
+--------+
| @total |
+--------+
|    172 |
+--------+

解析:

  • delimiter是分割符的意思。因为MySQL默认以“;”为分割符,如果没有声明分割符,那么编译器会把存储过程当作SQL语句进行处理,则存储过程的编译过程会报错。“delimiter //”声明分割符是“//”。存储过程中的代码结束之后,再次声明“delimiter ;”,将“;”作为分割符。

  • 创建的存储过程可能会有输入、输出、输入输出参数。本例有一个输入参数“ori”,类型是int,一个输出参数“total”,类型是int。如果有多个参数,用“,”分割开。

  • 过程体的开始、结束使用BEGIN和END进行标识。

  • MySQL称存储过程的执行为调用,因此执行存储过程的语句是CALL。CALL接收存储过程的名字以及需要传递给它的任何参数。

2、参数:

存储过程共有三种参数类型,INT、OUT、INOUT。形式如:CREATE PROCEDURE([[IN |OUT |INOUT ] 参数名 数据类形...])

  • IN输入参数:该参数的值必须在调用存储过程时指定。如果在存储过程中修改了该参数的值,该参数的值仍然是修改之前的值。

  • OUT输出参数:指定MySQL变量,接收调用存储过程后返回的值。

  • INOUT输入输出参数:调用时指定,并且可被改变和返回。

3、变量:

  • 定义存储过程局部变量:

DECLARE variable_name datatype [default value];

datatype与MySQL的数据类型一样,如:int、float、date、varchar(length);

  • MySQL变量:MySQL变量一般以@开头;

  • 变量赋值:

SET variable_name = value

4、查询存储过程:

# 列出所有的存储过程:
mysql> show procedure status\G# 列出某个库拥有的存储过程:
mysql> select name from mysql.proc where db='project';
# 查询存储过程的详细信息:
mysql> show create procedure project.originplayer;

5、删除存储过程:

mysql> drop procedure project.originplayer;

游标相关:

1、创建游标:

mysql> DELIMITER //
mysql> CREATE PROCEDURE `getplayerid`()-> BEGIN->   DECLARE id int(11);->   DECLARE done BOOLEAN DEFAULT 0;->   DECLARE cur CURSOR FOR SELECT->     playerid->   FROM player;->   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;->   OPEN cur;->     REPEAT->       FETCH cur into id;->     UTIL done END REPEAT;->   CLOSE cur;-> END//
mysql> DELIMITER ;

解析:

  • MySQL游标仅用于存储过程中;

  • DECLARE语句用来定义和命名游标,这里的游标为“cur”;

  • OPEN和CLOSE用来打开和关闭游标。在处理OPEN语句时执行查询,存储检索出的数据以供浏览。CLOSE游标将释放游标占用的所有内存和内部资源。如果没有明确关闭游标,MySQL会在到达END语句时自动关闭游标;

  • 在一个游标被打开后,使用FETCH语句可以访问游标的每一行,并可以指定将数据存储在什么地方。

  • 上面例子中,FETCH语句在REPEAT内,因此它反复执行,直到done为真(由UTIL done END REPEAT;指定);

  • CONTINUE HANDLER,当REPEAT由于没有更多的行供循环而不能继续时出现这个条件,将done设置为1,此时REPEAT终止。

2、DECLARE语句的次序:

DECLARE语句的发布存在特定的次序。用DECLARE语句定义的局部变量必须在定义任意游标或句柄之前;句柄的定义必须在游标之后。

3、重复或循环:

除了在1、创建游标中使用的REPEAT外,MySQL还支持循环语句,用来重复执行代码,直到使用LEAVE语句手动退出为止。如下:

    ……->     read_loop:LOOP->       -- 提取游标中的数据->       FETCH cur INTO id,origin;->       -- 声明何时结束循环->       IF done THEN->         LEAVE read_loop;->       END IF;->       -- 循环时的事件->       IF origin=0->       THEN->         INSERT INTO consumption VALUES (0,1525467600);->       ELSE->         INSERT INTO consumption_other VALUES(0,1525467600);->       END IF;->     END LOOP;……

转载于:https://blog.51cto.com/13568014/2117678

记一次MySQL存储过程和游标的使用相关推荐

  1. MySQL存储过程中游标使用

    在使用游标的时候,使用LOOP没有响应,后找到使用REPEAT实现,以下是代码: 建表语句 DROP table IF EXISTS test_table; create table test_tab ...

  2. MySQL存储过程使用游标循环数据列表

    本篇文章主要讲解,我的一个案例,使用存储过程和游标循环数据列表,并且做一些操作,比如保存一些数据,修改一些数据: 1.需求? MySQL使用存储过程循环数据列表? 2.先描述下MySQL有哪些循环的语 ...

  3. mysql存储过程之游标遍历数据表

    今天写一个mysql存储过程,根据自己的需求要遍历一个数据表,因为对存储过程用的不多,语法不甚熟悉,加之存储过程没有调试环境,花了不少时间才慢慢弄好,故留个痕迹. ? 1  BEGIN  2      ...

  4. Mysql存储过程和游标的一点理解

    最近学习数据库语言sql,学到了存储过程和游标这一块,上课一点没听,可以说是全程懵逼.不过好在有个课后的实验,然而cmd中的报错往往极其粗糙,只会告诉你什么附近有错(有时候还是错的),在不知error ...

  5. MySQL存储过程和游标

    MySQL5 中添加了存储过程的支持.     大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成     存储过程简单来说,就是为以后的 ...

  6. mysql游标进阶_MYSQL进阶学习知识拓展一:MySQL 存储过程之游标!

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

  7. mysql存储过程之游标

    MySQL5 中添加了存储过程的支持.     大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成     存储过程简单来说,就是为以后的 ...

  8. mysql存储过程触发器游标_MySQL存储过程,触发器,游标

    语法: 1.存储过程: create PROCEDURE name(argment_list) begin sql_statement; end 2.触发器: create trigger name ...

  9. mysql存储过程和游标遍历

    DELIMITER $$ CREATE PROCEDURE alarm_replay_insert_procedure() BEGIN-- 定义变量 DECLARE _nowTime DATETIME ...

最新文章

  1. javascript函数、对象及变量、正则表达式(7.19)
  2. redis入门及java操作
  3. 我的Ubuntu9.10安装与配置100
  4. C++静态成员和静态成员函数
  5. spring 入门 1
  6. 安全是什么意思_屈老师小班安全教案《安全标志》
  7. 荣耀A55高调上市仅仅为孤独求败?
  8. 开课吧:Html5有哪些新特性?
  9. R语言编程艺术(4)R对数据、文件、字符串以及图形的处理
  10. vba单元格批量赋值_「经验」快速学习VBA
  11. 全网首发:TeaVM编译时容易出错的几种代码
  12. 1.4-shell中特殊符号
  13. 全站仪数据导入电脑_怎么把全站仪的数据导到电脑上来,并且成图?
  14. 【STM32入门】STM32基础理论知识
  15. 贴吧怎么发帖,发防删图出现审核怎么办?
  16. 记事狗微博php,记事狗微博系统_366rtc
  17. 拼多多数据分析一二三面面经(HR面后综排挂)
  18. memtester4.3.0
  19. Oracle开启binlog
  20. mysql 客户端SSL错误2026 (HY000)

热门文章

  1. 7-81 单词长度 (15 分)
  2. 鸿蒙系统对手机性能的提升,鸿蒙OS手机版再爆新特性,流畅度和性能大幅提升,用户评价很高...
  3. 基于顺序存储结构的图书信息表的图书去重(C++)
  4. python获取文件夹里有什么文件+查看特定格式的文件
  5. linux root密码激活,Linux - root初始密码设置
  6. SecureCRT突然卡死的问题
  7. 127.Word Ladder
  8. ipython的使用
  9. C#实现多级子目录Zip压缩解压实例
  10. Python2.7编程基础(博主推荐)