一、游标

定义:是一个存储在MySQL服务器上的数据库查询,是一种被select语句检索出来的结果集。

作用:方便在检索出来的结果集中前进或后退一行或多行。

PS:游标主要用于交互式应用;MySQL中的游标只能用于存储过程(和函数)。

1、创建游标

游标使用declare语句创建;declare命名游标,并定义相应的select语句,根据需要带where和其他子句;例如:

create procedureprocessorders()begin

declare ordernumbers CURSOR

for

select order_num fromorders;end;

这个存储过程中,declare定义和命名了游标ordernumbers,存储过程处理完成后,游标就消失(局限于存储过程内)。

2、打开和关闭游标

定义游标之后,可以打开它,用open cursor语句来打开,例如:open ordernumbers;

在处理open语句时执行查询,存储检索出的数据以供浏览和滚动;

游标处理完成时,用close语句关闭,例如:close ordernumbers;

close释放游标使用的所有内部内存和资源,因此在每个游标不在需要时都应该关闭。

PS:

游标关闭后,如果没有重新打开,则不能使用;但如果该游标被声明过,则不需要再次声明,用open打开使用即可。

如果不明确游标是否关闭,MySQL将会在到达end语句时自动关闭该游标。

3、使用游标数据

游标被打开后,使用fetch语句分别访问它的每一行;fetch指定检索什么数据(所需的列),检索的数据存储在什么地方,还向前移动游标中的内部行指针,使下一条fetch语句检索下一行(不重复读取)。

检索第一行数据,例如:

create procedureprocessorders()begin

--declare local variables

declare o int;--declare the cursor

declare ordernumbers cursor for select order_num fromorders;--open the cursor

openordernumbers;--get order number

fetch ordernumbers intoo;--close the cursor

closeordernumbers;end;

这条语句中fetch用来检索当前行的order_num列(自动从第一行开始)到一个名为o的局部声明变量中;对检索出的数据不做任何处理。

循环检索数据,从第一行到最后一行,如下:

create procedure processorders() --创建存储过程

begin

--declare local variables

declare done boolean default 0;declare 0 int;--declare the cursor

declare ordernumbers cursor

for select order_num from orders; --结果集

--declare continue handler

declare continue handler for sqlstate '02000' set done=1; --在这里,done被设置为结束时为真

--open the cursor

openordernumbers;--loop through all rows

repeat--get order number

fetch ordernumbers intoo;--end of loop

until done endrepeat;--close the cursor

closeordernumbers;end;

与前一个例子一样,用fetch检索当前order_num到声明的o变量中。区别在于:这个例子中fetch是在repeat内,因此它反复执行到done为真(由until done end repeat;规定)。

在语句(declare continue handler for sqlstate '02000' set done=1;)中,定义了CONTINUE HANDLER,它是在条件出现时被执行的代码。当SQLSTATE '02000'出现时,SET done=1。

SQLSTATE '02000'是一个未找到条件,当REPEAT由于没有更多的行供循环而不能继续时,出现这个条件。done被设置为真。

PS:

用declare语句定义的局部变量必须在定义任意游标或句柄之前定义,而句柄必须在游标之后定义。

MySQL还支持循环语句,它可用来重复执行代码,直到使用leave语句手动退出为止;通常repeat语句的语法使它更适合于对游标进行循环。

4、使用游标的几个注意事项

1、在使用游标前,必须声明(定义)它;这个过程实际没有检索数据,只是定义要使用的select语句;

2、一旦声明,则必须打开游标以供使用(这个过程用前面定义的select语句把数据实际检索出来);

3、对于填有数据的游标,根据需要取出(检索)各行;

4、结束游标使用时,必须关闭游标。

二、触发器

MySQL语句在需要时被执行,存储过程也是如此,如果希望某条语句(或某些语句)在事件发生时自动执行,这就需要用到触发器。

触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于begin和end语句之间的一组语句):delete;insert;update。其他MySQL语句不支持触发器。

1、创建触发器

需要的信息:唯一的触发器名;触发器关联的表;触发器应该响应的活动(delete、insert或update);触发器何时执行(处理之前或之后)。

PS:MySQL中,触发器名必须在每个表中唯一,但不是在每个数据库中唯一。即:同一数据库中两个表可以具有相同名字的触发器,但其他的DBMS中不被允许,所以最好是在数据库范围内使用唯一的触发器名。

触发器使用create teigger语句创建,如:

create trigger newproduct after insert onproductsfor each row select 'product added';

创建newproduct触发器,给出了after insert,所以此触发器在insert语句成功执行后执行;还指定了for each row,因此代码对每个插入行执行。

PS:

1、只有表才支持触发器,视图不支持(临时表也不支持)。

2、触发器按每个表每个事件每次的定义,每个表每个事件每次只允许一个触发器;因此每个表最多支持6个触发器(每条insert、update和delete的之前和之后),单一触发器不能与多个事件或多个表关联。

3、如果before触发器失败,则MySQL将不执行请求的操作;此外,如果before触发器或语句本身失败,MySQL将不执行after触发器(如果有的话)。

2、删除触发器

删除触发器用drop trigger语句,如:

drop trigger newproduct;

PS:触发器不能更新或覆盖;为了修改一个触发器,必须先删再建。

3、使用触发器

1、insert触发器

使用insert触发器,需要知道以下三点:

1、在insert触发器代码内,可引用一个名为new的虚拟表,访问被插入的行;

2、在before insert触发器内,new中的值也可以被更新(允许更改被插入的值);

3、对于auto increment列,new在insert执行之前包含0,在insert执行之后包含新的自动生成值;

对于AUTO_INCREMENT自动赋予的值,确定新生成值的方法,例子如下:

create trigger neworder after insert onordersfor each row select new.order_num;

创建一个名为neworder的触发器,按照after insert on order执行;在插入一条新的数据到orders表时,MySQL生成一个新订单号并保存到order_num中;

触发器从new.order_num取这个值并返回它;此触发器必须按照after insert执行,因为在before insert语句执行之前,新order_num还没生成。

PS:通常将before用于数据验证和净化(目的是保证插入表中的数据确实是需要的数据)。这个规则也适用于update触发器。

2、delete触发器

使用delete触发器,需要知道以下两点:

1、在delete触发器代码内,可以引用一个名为old的虚拟表,访问被删除的行;

2、old中的值全都是只读的,不能更新;

使用old保存将要被删除的行到一个存档表中:

create trigger deleteorder before delete onordersforeach rowbegin

insert intoarchive_orders(order_num,order_date,cust_id)values(OLD_order_num, OLD_order_date, OLD_cust_id);end;

在任意数据被删除前执行此触发器;它使用insert语句将old中的值(要被删除的数据)保存到一个名为archive_orders的存档表中;

PS:使用begin end块的好处是触发器能容纳多条SQL语句。

3、update触发器

使用update触发器,需要知道以下三点:

1、在update触发器代码内,可以引用一个名为old的虚拟表访问以前(update语句前)的值,引用一个名为new的虚拟表访问新更新的值;

2、在before update触发器中,new中的值可能也被更新(允许更改将要用于update语句中的值);

3、old中的值全都是只读的,不能更新;

下面的例子,保证了州名称缩写总是大写:

create trigger updateevendor before update onvendorsfor each row set new.vend_state = upper(new.vend_state);

每次更新一个行时,new.vend_state中的值都用upper(new.vend_state)替换。

4、关于触发器一些必须知道的知识:

1、创建触发器可能需要特殊的安全访问权限,但触发器的执行是自动的。如果insert、update或delete语句可以执行,则相应触发器也能执行;

2、应该用触发器来保证数据的一致性(大小写、格式等);优点在于它总是进行这种处理,而且是透明的进行,与客户机应用无关;

3、触发器的一种非常有意义的使用是创建审计跟踪。使用触发器,把更改记录到另一个表非常容易;

4、MySQL触发器不支持call语句,即不能从触发器内调用存储过程。所需的存储过程代码需要复制到触发器内。

mysql游标触发器批量_MySQL游标和触发器相关推荐

  1. mysql begin end 用法_MySQL ------ 游标(CURSOR)(二十六)

    MySQL执行检索操作会返回一组称为结果集的行,这组返回的行都是与SQL 语句相匹配的行(零行或多行),但是,使用简单的select 语句,没有办法得到第一行.下一行.或前十行,也不存在一行地处理所有 ...

  2. mysql嵌套loop循环_mysql游标嵌套循环

    最近在mysql开发过程中用到了游标的嵌套循环,下面列举了3种嵌套循环(loop-loop,loop-while,loop-repeat). 程序用到的表和数据 CREATE TABLE tb_dic ...

  3. mysql 游标 时间类型_mysql 游标类型

    mysql里面不可以返回游标,很让人蛋疼,没oracle好,而且,mysql没有什么好的调试工具,也比较纠结. 下面是我写的一个mysql存储过程,里面使用到了游标,临时表,最终返回的是结果接,希望对 ...

  4. mysql采用 级触发_Mysql高级之触发器(trigger)

    触发器是一类特殊的事务 ,可以监视某种数据操作(insert/update/delete),并触发相关操作(insert/update/delete). 看以下事件: 完成下单与减少库存的逻辑 Ins ...

  5. mysql游标的概述_MySQL游标简介

    mysql> delimiter // mysql> mysql> create procedure test1() -> begin -> declare l_add_ ...

  6. mysql 自定义函数 事务_MySQL存储过程、触发器、自定义函数、事务

    1.存储过程 MySQL中存储过程的参数中有IN.OUT.INOUT类型,但是函数的参数只能是IN类型的. "in" 参数:跟 C 语言的函数参数的值传递类似, MySQL 存储过 ...

  7. mysql存储过程语法和游标的语法_MySQL游标存储过程-语法点滴

    CREATE PROCEDURE my_proc() BEGIN -- 需要定义接收游标数据的变量 DECLARE sname VARCHAR(100); DECLARE cattype VARCHA ...

  8. mysql 游标 多字段_MySQL 游标使用 多字段

    CREATE DEFINER=`root`@`localhost` FUNCTION `FUN_FIX_RECEIPT_CONTENT_PAYMENT`(accountStartDay varchar ...

  9. mysql有没有批量游标_MySQL使用游标批量处理进行表操作_MySQL

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

最新文章

  1. Adobe Flash player 10 提示:Error#2044:未处理的IOErrorEvent. text=Error#2036:加载未完成 的解决方法
  2. android多屏幕适配注意几点
  3. MyBatis传入多个参数的问题
  4. 【思维】中位数与顺序统计
  5. JavaEE是什么?
  6. python基础——注释、字符串、输出换行
  7. java中所有函数都是虚函数_关于Java:虚拟函数与纯虚函数之间的区别是什么?...
  8. 第三章 阴阳的工作机制(1)
  9. JSP、Servlet中get请求和post请求的区别总结
  10. 笨人学php好学吗_平面设计学多久能上手 好学吗
  11. 3.5 訪问者模式(5.11)
  12. 第五章 多个消费者监听同一个队列
  13. python画散点图 不同属性赋予不同颜色
  14. 股票交易软件接口编程语言
  15. CSS 中的层叠,层级关系
  16. html在线打印插件,jQuery简单易用的网页内容打印插件
  17. 腾讯互娱技术总监张正:《天涯明月刀》后台技术创新
  18. B站李旎:学习类内容正从B站开始兴起
  19. MongoDB 查询昨日/昨天数据
  20. CAN通讯原理简介(一)

热门文章

  1. 批量修改一张表格的多个sheet名
  2. 如何让div在整个页面中居中?
  3. 数据驱动工程:跟踪使用,合理决策
  4. PHP中include与require的特点和区别说明
  5. 【计算机视觉】基于Shading Model(对光照变化一定不变性)的运动目标检测算法...
  6. iOS-UIScrollView拉伸效果
  7. No resource found that matches the given name 'Theme.AppCompat.Light'.
  8. Js 对象添加属性
  9. PhpStrom 配置Xdebug
  10. 组件注册@ComponentScan的自动扫描和指定扫描规则