MySQL数据库高级(五)——触发器

MySQL数据库高级(五)——触发器

一、触发器简介

1、触发器简介

触发器是和表关联的特殊的存储过程,可以在插入,删除或修改表中的数据时触发执行,比数据库本身标准的功能有更精细和更复杂的数据控制能力。

2、触发器的优点

A、安全性
可以基于数据库的值使用户具有操作数据库的某种权利。可以基于时间限制用户的操作,例如不允许下班后和节假日修改数据库数据;可以基于数据库中的数据限制用户的操作,例如不允许股票的价格的升幅一次超过10%。
B、审计
可以跟踪用户对数据库的操作。???审计用户操作数据库的语句;把用户对数据库的更新写入审计表。
C、实现复杂的数据完整性规则
实现非标准的数据完整性检查和约束。触发器可产生比规则更为复杂的限制。与规则不同,触发器可以引用列或数据库对象。例如,触发器可回退任何企图吃进超过自己保证金的期货。提供可变的缺省值。
D、实现复杂的非标准的数据库相关完整性规则。
触发器可以对数据库中相关的表进行连环更新。
??在修改或删除时级联修改或删除其它表中的与之匹配的行。
??在修改或删除时把其它表中的与之匹配的行设成NULL值。
在修改或删除时把其它表中的与之匹配的行级联设成缺省值。
??触发器能够拒绝或回退那些破坏相关完整性的变化,取消试图进行数据更新的事务。
E、同步实时地复制表中的数据。
F、SQL触发器提供了运行计划任务的另一种方法。自动计算数据值,如果数据的值达到了一定的要求,则进行特定的处理。例如,如果公司的帐号上的资金低于5万元则立即给财务人员发送警告数据。

3、触发器的限制

A、触发程序不能调用将数据返回客户端的存储程序,也不能使用采用CALL语句的动态SQL语句,但是允许存储程序通过参数将数据返回触发程序,也就是存储过程或者函数通过OUT或者INOUT类型的参数将数据返回触发器是可以的,但是不能调用直接返回数据的过程。
B、不能在触发器中使用以显示或隐式方式开始或结束事务的语句,如START TRANS-ACTION,COMMIT或ROLLBACK。

二、触发器的使用

1、创建触发器

创建触发器的语法:
CREATE TRIGGER trigger_name trigger_time trigger_event ON tb_name FOR EACH ROW trigger_stmt
trigger_name:触发器的名称。
tirgger_time:触发时机,为BEFORE或者AFTER。
trigger_event:触发事件,为INSERT、DELETE或者UPDATE。
tb_name:表示建立触发器的表名,在哪张表上建立触发器。
trigger_stmt:触发器的程序体,可以是一条SQL语句或者是用BEGIN和END包含的多条语句。
FOR EACH ROW表示任何一条记录上的操作满足触发事件都会触发该触发器。
MySQL除了对INSERT、UPDATE、DELETE基本操作进行定义外,还定义了LOAD DATA和REPLACE语句,这两种语句也能引起上述6中类型的触发器的触发。
LOAD DATA 语句用于将一个文件装入到一个数据表中,相当与一系列的 INSERT操作。
REPLACE语句一般来说和INSERT语句很像,只是在表中有primary key或 unique索引时,如果插入的数据和原来primary key或unique索引一致时,会先删除原来的数据,然后增加一条新数据。
INSERT型触发器:插入某一行时激活触发器,通过 INSERT、LOAD DATA、REPLACE语句触发;
UPDATE型触发器:更改某一行时激活触发器,通过UPDATE语句触发;
DELETE型触发器:删除某一行时激活触发器,通过DELETE、REPLACE语句触发。
变量声明:
DECLARE var_name[,...] type [DEFAULT value]
对变量赋值采用SET 语句,语法为:
SET var_name = expr [,var_name = expr] ...
MySQL中定义了NEW和OLD,用来表示触发器的所在表中,触发了触发器的那一行数据。
在INSERT型触发器中,NEW用来表示将要(BEFORE)或已经(AFTER)插入的新数据;
在UPDATE型触发器中,OLD用来表示将要或已经被修改的原数据,NEW用来表示将要或已经修改为的新数据;
在DELETE型触发器中,OLD用来表示将要或已经被删除的原数据;
使用方法:NEW.columnName(columnName为相应数据表某一列名)
另外,OLD是只读的,而NEW则可以在触发器中使用SET赋值,不会再次触发触发器,造成循环调用。

2、删除触发器

DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
schema_name是数据库的名称,是可选的。如果省略了schema,将从当前数据库中舍弃触发程序。trigger_name是要删除的触发器的名称。

3、触发器信息查看

在MySQL中,所有的触发器的定义都存在于INFORMATION_SCHEMA数据库的triggers表中,可以通过查询命令SELECT来查看,具体语法如下:
SHOW TRIGGERS [FROM schema_name];

触发器的执行顺序
InnoDB数据库,若SQL语句或触发器执行失败,MySQL会回滚事务,有:
A、如果BEFORE触发器执行失败,SQL无法正确执行。
B、SQL执行失败时,AFTER型触发器不会触发。
C、AFTER类型的触发器执行失败,SQL会回滚。
MySQL的触发器是按照BEFORE触发器、行操作、AFTER触发器的顺序执行的,其中任何一步发生错误都不会继续执行剩下的操作,如果对事务表进行的操作,如果出现错误,那么将会被回滚,如果对非事务表进行操作,那么就无法回滚,数据可能会出错。

三、触发器应用

1、实现业务逻辑

客户下订单订购商品,商品表自动减少数量。
在商品表创建删除触发器,删除某商品,自动删除该商品的订单。
创建产品表,有产品编号,产品名称、产品数量和产品价格四列,其中产品编号自增长列,并设置成主键。

create table product
(
pid int PRIMARY KEY AUTO_INCREMENT,
pname VARCHAR(10),
price DOUBLE,
pnum INT
)ENGINE=innoDB default CHARSET=utf8;

创建订单表,有三列,订单编号、产品编号和数量,其中订单编号自增长列,并设置成主键。

create table orders
(
oid INT PRIMARY KEY AUTO_INCREMENT,
pid INT,
onum INT
)ENGINE=innoDB DEFAULT CHARSET=utf8;

插入三种产品,产品名称和数量以及价格。

insert into product(pname, pnum, price)values(‘桃子‘, 100, 2);
insert into product(pname, pnum, price)values(‘苹果‘, 80, 8);
insert into product(pname, pnum, price)values(‘香蕉‘, 50, 5);


在订单表上创建触发器,当有订单,会根据订单的产品编号和数量自动减少产品的数量。触发器中NEW代表一个表,存放插入的订单记录。

create trigger trigger_order
AFTER INSERT ON orders FOR EACH ROW
BEGIN
UPDATE product SET pnum=pnum-NEW.onum where pid = NEW.pid;
END

插入两个订单

INSERT INTO orders(pid, onum)VALUES(1, 10);
INSERT INTO orders(pid, onum)VALUES(2, 5);

查看产品表,可以看到对应的产品数量减少。操作由订单表的Insert触发器完成。

在订单表上创建新的触发器,当订单定的某产品产品数量大于产品库存,禁止下订单,也就是禁止在订单表中插入记录。
一张表中只能有一个INSERT类型的触发器,先删除INSERT触发器。
drop trigger trigger_order;
MySQL不能在触发器中通过回滚事务取消操作,但如果触发器的SQL语句执行过程中出现错误,会自动撤销操作,曲线实现事务回滚。

create trigger trigger_order
BEFORE INSERT ON orders FOR EACH ROW
BEGIN
DECLARE var int;
DECLARE mesg varchar(20);
SELECT pnum INTO var FROM product where pid=NEW.pid;
IF var<NEW.onum
   THEN  SELECT XXXX INTO mesg;
ELSE
   UPDATE product SET pnum=pnum-NEW.onum where pid=NEW.pid;
END IF;
END

插入订单,看看如果库存不够是否还能够插入成功。
INSERT INTO orders(pid, onum)VALUES(1, 110);

2、实现安全

A、限制插入记录的日期
在订单表上创建插入触发器,周六周日不允许下订单。

create trigger trigger_limitDate
BEFORE INSERT ON orders FOR EACH ROW
BEGIN
DECLARE mesg varchar(10);
IF DAYNAME(now())=‘sunday‘ or DAYNAME(now())=‘saturday‘
   THEN SELECT XXXXX INTO mesg;
ELSE
   SET mesg=‘允许插入订单‘;
END IF;
END

验证上面创建的触发器是否工作正常,看看当前时间是否是周六周日,向订单表插入记录,检查是否能够成功。
insert into orders(pid,onum) values (3,30)
B、限制数据更改的范围
在产品表上创建更新触发器,限制产品价格一次上调不能超过20%。
触发器设置成before update,在更改前检查价格增长幅度是否超过20%,如果超过就产生错误,取消操作。
更新操作分为两步,第一步是删除原来的记录,第二步是插入新记录。原来的记录在old表中,新记录在new表中。触发器中new.price存放的是新价格,old.price是原来的价格。

create trigger trigger_limitIncreasePrice
BEFORE UPDATE ON product FOR EACH ROW
BEGIN
DECLARE mesg varchar(10);
if (NEW.price-OLD.price)*100/OLD.price > 20
   then select XXXX into mesg;
else
   set mesg=‘更改成功‘;
end if;
END

验证触发器
update product set price=20 where pid=1;

3、实现数据完整性

使用触发器可以限制表插入某列的数值范围。
创建一个学生表,有四列,姓名、性别、手机和邮箱。

create table personinfo
(
sname VARCHAR(5),
sex CHAR(1),
phone VARCHAR(11)
)ENGINE=innoDB default CHARSET=utf8;

A、指定性别列的取值范围
创建触发器,限制性别列,只允许输入“男”和“女”。before insert触发器,不满足条件执行有错误的SQL语句,退出。

create trigger trigger_limitSex
before insert on personinfo for each row
begin
declare mesg varchar(10);
if NEW.sex=‘男‘ or NEW.sex=‘女‘
then
   set mesg=‘更改成功‘;
else
   select xxxx into mesg;
end if;
End

验证触发器

insert into personinfo VALUES(‘孙悟空‘, ‘难‘,‘18900000000‘);
insert into personinfo VALUES(‘唐僧‘, ‘男‘,‘18900000001‘);

B、限制手机列的取值类型和长度
创建触发器,只允许phone列输入的手机号只能是11位数字,且第一位数字是1。

create trigger trigger_limitPhone
before insert on personinfo for each row
begin
declare mesg varchar(10);
if NEW.phone regexp ‘[1][0-9]{10}‘
   then set mesg=‘插入成功‘;
else
   select xxxx into mesg;
end if;
End

验证触发器,如果手机列插入的值位数不对或者第一位不是1,插入都将失败。
insert into personinfo VALUES(‘唐僧‘, ‘男‘,‘2890000001‘);

4、使用触发器审计

使用触发器实现对personinfo表数据操作的跟踪,将跟踪事件记录到一张审计表中review。

create table review
(
username VARCHAR(20),
action VARCHAR(10),
studentID CHAR(5),
sname CHAR(10),
actionTime TIMESTAMP
);

A、创建触发器记录插入操作

create trigger trigger_insert
before insert on personinfo for each row
begin
insert into review values(user(),‘insert‘,new.sname,now());
End

插入personinfo表一条记录
insert into personinfo values(‘孙悟空‘, ‘男‘, ‘13008080808‘);
查看review表中增加的INSERT记录
select * from review

B、创建触发器记录删除操作

create trigger trigger_delete
after DELETE on personinfo for each row
begin
insert into review values(user(),‘delete‘,old.sname,now());
End

从personinfo删除一条记录
delete from personinfo where sname=‘孙悟空‘;
查看reivew表中增加的DELETE记录

C、创建触发器记录修改操作

create trigger trigger_update
after UPDATE on personinfo for each row
begin
insert review values(user(),‘update‘,new.sname,now());
End

更新personinfo表中名字为‘孙悟空’的phone。
update personinfo set phone=‘189080808‘ where sname=‘孙悟空‘;
查看reivew表中增加的UPDATE记录

原文地址:http://blog.51cto.com/9291927/2095105

时间: 2024-11-09 15:05:02

MySQL数据库高级(五)——触发器的相关文章

MySQL数据库高级(六)——索引

MySQL数据库高级(六)--索引 一.索引简介 1.索引简介 索引(Index)是帮助MySQL高效获取数据的数据结构.在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的.MyISAM和InnoDB存储引擎只支持BTREE索引,MEMORY/HEAP存储引擎支持HASH和BTREE索引. 2.索引的优点 A.提高数据检索效率,降低数据库的IO成本.B.通过索引对数据进行排序,降低数据排序的成本,降低了CPU的消耗.C.大大加快数据的查询速度. 3.索引的缺点 A.

MySQL数据库高级(九)——游标

MySQL数据库高级(九)--游标 一.游标简介 1.游标简介 游标的设计是一种数据缓冲区的思想,用来存放SQL语句执行的结果.游标是一种能从包括多条数据记录的结果集中每次提取一条记录的机制.尽管游标能遍历结果中的所有行,但一次只指向一行.游标的作用就是用于对查询数据库所返回的记录进行遍历,以便进行相应的操作. 2.游标的特性 游标具有三个属性:A.不敏感(Asensitive):数据库可以选择不复制结果集B.只读(Read only)C.不滚动(Nonscrollable):游标只能向一个方向

MySQL数据库高级(二)——自定义函数

MySQL数据库高级(二)--自定义函数 一.自定义函数简介 自定义函数 (user-defined function UDF)是一种对MySQL扩展的途径,其用法和内置函数相同.自定义函数的两个必要条件:A.参数B.返回值(必须有).函数可以返回任意类型的值. 二.自定义函数的使用 1.自定义函数语法 CREATE?FUNCTION?function_name(parameter_nametype,[parameter_name type,...]) RETURNS?{STRING|INTEG

MySQL数据库高级(三)——视图

MySQL数据库高级(三)--视图 一.视图简介 1.视图简介 视图是由SELECT查询语句所定义的一个虚拟表,是查看数据的一种非常有效的方式.视图包含一系列带有名称的数据列和数据行,但视图中的数据并不真实存在于数据库中,视图返回的是结果集. 2.创建视图的目的 视图是存储在数据库中的查询的SQL语句,创建视图主要出于两种原因:A.实现安全.视图可设置用户对视图的访问权限.创建查询是JAVA班学生成绩的视图javaview.NET班学生成绩的视图netview,授权zhang能够访问javavi

MySQL数据库高级(四)——存储过程

MySQL数据库高级(四)--存储过程 一.存储过程简介 1.存储过程简介 存储过程是一组具有特定功能的SQL语句集组成的可编程的函数,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数来调用执行.存储过程是数据库管理中常用的技术之一,可以很方便的做些类似数据统计.数据分析等工作,SQL SERVER.ORACLE.MySQL都支持存储过程,但不同的数据库环境语法结构有所区别. 2.存储过程的优点 A.存储过程增强了SQL语言的功能和灵活性.存储过程可以用流控制语句编写,有很强的

mysql数据库优化五步走

MySQL数据库是一种小型关系型数据库管理系统,MySQL数据库的优化是MySQL数据库操作过程中非常重要的工作,MySQL数据库的优化能够实现MySQL数据库操作的简便. 第一步: 1:磁盘寻道能力,以高速硬盘(7200转/秒),理论上每秒寻道7200次.这是没有办法改变的,优化的方法是----用多个硬盘,或者把数据分散存储. 2:硬盘的读写速度,这个速度非常的快,这个更容易解决--可以从多个硬盘上并行读写. 3:cpu.cpu处理内存中的数据,当有相对内存较小的表时,这是最常见的限制因素.

MYSQL数据库学习八 触发器的操作

8.1 触发器 在表发生更改时,自动进行一些处理.例如,学生表中每增加一条关于学生记录时,学生的总数就必须同时改变,同时需要检查电话号码格式是否正确,地址缩写是否正确. 以下语句会激活触发器: DELETE语句. INSERT语句. UPDATE语句. MySQL 5开始支持触发器数据库对象. 8.2 创建触发器 CREATE TRIGGER trigger_name BEFORE|AFTER trigger_event ON table_name FOR EACH ROW trigger_st

MySQL数据库 高级查询(一)

常用函数 常用聚合函数: AVG() 返回某字段的平均值 COUNT() 返回某字段的行数 MAX() 返回某字段的最大值 MIN( ) 返回某字段的最小值 SUM( ) 返回某字段的和 函数名 作用 常用的字符串函数 函数名 作用 举例 CONCAT(str1,str2,...,strn) 连接字符串str1,str2,...,strn为一个完整字符串 SELECT CONCAT('My','S','QL'); 返回:MySQL INSERT(str,pos,len,newstr) 将字符串s

MySQL数据库(五)—— 用户管理、pymysql模块

用户权限管理.pymysql模块 一.用户管理(权限管理) 在MySQL中自带的mysql数据库中有4个表用于用户管理的 # 优先级从高到低 user > db > tables_priv > columns_priv user #该表放行的权限,针对:所有数据,所有库下所有表,以及表下的所有字段 db #该表放行的权限,针对:某一数据库,该数据库下的所有表,以及表下的所有字段 tables_priv #该表放行的权限.针对:某一张表,以及该表下的所有字段 columns_priv #该