一、游标

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

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

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

1、创建游标

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

create procedure processorders()

begin

declare ordernumbers CURSOR

for

select order_num from orders;

end;

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

2、打开和关闭游标

游标使用open cursor语句来打开,例如:

open ordernumbers;

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

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

close ordernumbers;

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

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

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

create procedure processorders()

begin

-- declare the cursor

declare ordernumbers cursor

for

select order_num from orders;

-- open the cursor

open ordernumbers;

-- close the cursor

close ordernumbers;

end;

这个存储过程声明、打开、关闭一个游标,但对检索出的数据没任何操作。

3、使用游标数据

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

create procedure processorders()

begin

--declare local variables

declare o int;

--declare the cursor

declare ordernumbers cursor for select order_num from orders;

--open the cursor

open ordernumbers;

--get order number

fetch ordernumbers into o;

--close the cursor

close ordernumbers;

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

open ordernumbers;

--loop through all rows

repeat

--get order number

fetch ordernumbers into0;

--end of loop

until done end repeat;

--close the cursor

close ordernumbers;

end;

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

为了使它起作用,用一个default 0(假、不结束)定义变量done;在语句(declare continue handler for sqlstate '02000' set done=1;)中done被设置为真。

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

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

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

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

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

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

④结束游标时,必须关闭游标。

二、触发器

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

触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于begin和end语句之间的一组语句):

delete;

insert;

update;

其他MySQL语句不支持触发器。。。

1、创建触发器

需要以下4条信息:

①唯一的触发器名;

②触发器关联的表;

③触发器应该响应的活动(delete、insert或update);

④触发器何时执行(处理之前或之后);

PS:MySQL中,触发器名必须在每个表中唯一,但不限制每个数据库中唯一,即:同一数据库中两个表可以具有相同名字的触发器(其他的DBMS中不被允许)。

触发器使用create teigger语句创建,下面是一个简单的例子:

create trigger newproduct after insert on products

for each row select 'product added';

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

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

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

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

2、删除触发器

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

drop trigger newproduct;

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

3、使用触发器

insert触发器

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

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

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

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

例子如下:

create trigger neworder after insert on orders

for 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触发器。

delete触发器

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

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

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

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

create trigger deleteorder before delete on orders
for each row
begin
insert into archive_orders(order_num,order_date,cust_id)
values(OLD_order_num, OLD_order_date, OLD_cust_id);
end;

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

上面的例子中,使用begin end块的好处是触发器能容纳多条SQL语句。

PS:使用before delete触发器的优点:如果由于某些原因,数据不能存档,delete本身将被放弃。

update触发器

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

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

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

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

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

create trigger updateevendor before update on vendors

for each row set.vend_state = upper(new.vend_state);

这个例子中,每次更新一个行时,new.vend_state中的值(将用来更新表行的值)都用upper(new.vend_state)替换。

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

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

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

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

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

MySQL(十二)游标和触发器的更多相关文章

  1. MYSQL存储过程、游标、触发器

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

  2. 我的MYSQL学习心得(十二) 触发器

    我的MYSQL学习心得(十二) 触发器 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数 ...

  3. 《mysql必知必会》4笔记(存储过程、游标、触发器、事务、全球化本地化、权限、数据库维护、性能)

    二十三:使用存储过程: 1:mysql 5添加了对存储过程的支持.很多时候,一个完整的操作需要多条语句才能完成.存储过程简单来说,就是为以后的使用而保存的一条或多条mysql语句的集合,可将其视为批文 ...

  4. 我的MYSQL学习心得(十二)

    原文:我的MYSQL学习心得(十二) 我的MYSQL学习心得(十二) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYS ...

  5. MySQL笔记 存储过程 游标 触发器

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

  6. 进击的Python【第十二章】:mysql介绍与简单操作,sqlachemy介绍与简单应用

    进击的Python[第十二章]:mysql介绍与简单操作,sqlachemy介绍与简单应用 一.数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数 ...

  7. Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)

    Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 目录 Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 1 Internal Locking Methods Row-Leve ...

  8. mysql进阶(二十九)常用函数

    mysql进阶(二十九)常用函数 一.数学函数 ABS(x) 返回x的绝对值 BIN(x) 返回x的二进制(OCT返回八进制,HEX返回十六进制) CEILING(x) 返回大于x的最小整数值 EXP ...

  9. mysql进阶(二十八)MySQL GRANT REVOKE用法

    mysql进阶(二十八)MySQL GRANT REVOKE用法   MySQL的权限系统围绕着两个概念: 认证->确定用户是否允许连接数据库服务器: 授权->确定用户是否拥有足够的权限执 ...

随机推荐

  1. 5大JavaScript前端框架简介

    译者按: 简要介绍五大前端框架特性 原文: Top 5 JavaScript Frameworks 译者: Fundebug 为了保证可读性,本文采用意译而非直译.另外,本文版权归原作者所有,翻译仅用 ...

  2. Node.js+Koa开发微信公众号个人笔记(一)准备工作

    本人也是在学习过程中,所以文章只作为学习笔记,如果能帮到你,那就更好啦~当然也难免会有错误,请不吝指出~ 一.准备工作 1.本人学习教程:慕课网Scott老师的<Node.js七天搞定微信公众号 ...

  3. webpack打包时排除其中一个css、js文件,或单独打包一个css、js文件

    在项目中经常会需要将一些接口的配合文件或者某些样式文件,分离出来单独打包,便于后期改动,这里我以css文件为例,介绍实现两种方法: 项目目录: 如上图所示,现在我需要将项目中的scBtn.css文件单 ...

  4. loadrunner 脚本开发-文件读写操作

    脚本开发-文件读写操作 by:授客 QQ:1033553122 函数说明 函数原型: size_t fwrite( const void *buffer, size_t size, size_t co ...

  5. Android 2018最新验证手机号正则表达式

    /** * 判断字符串是否符合手机号码格式 * 移动号段: 134,135,136,137,138,139,147,150,151,152,157,158,159,170,178,182,183,18 ...

  6. 对word2vec的理解及资料整理

    对word2vec的理解及资料整理 无他,在网上看到好多对word2vec的介绍,当然也有写的比较认真的,但是自己学习过程中还是看了好多才明白,这里按照自己整理梳理一下资料,形成提纲以便学习. 介绍较 ...

  7. 四则运算 Java 姚康友,黎扬乐

    github项目传送门:https://github.com/yaokangyou/arithmetic 项目要求 功能列表 [完成] 使用 -n 参数控制生成题目的个数 [完成] 使用 -r 参数控 ...

  8. 查看python版本

    1.未进入python shell python --version 2.进入python shell,有两种方法 (1) help() (2) import sys sys.version

  9. cmder个人配置文件,做个记录

    以下附件是自己的cmder配置文件: https://app.yinxiang.com/shard/s13/res/30e84035-5f0f-4baf-b18c-a84ce45ec8b9/wkkcm ...

  10. 【PAT】B1057 数零壹(20 分)

    简单题,简单字符串处理加简单数学进制转换 #include<stdio.h> #include<string.h> #include<ctype.h> int ma ...