1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
-----/*触发器*/
--满足触发条件时就会。自动执行。触发器中的语句,可以保证某些操作之间的一致性
--可以层叠更改,可以引用其他表中的列
--事前触发器可以获取事前之前和新的字段值,验证一些条件和进行一些准备操作,在表保存之前触发*/
--事后触发器是进行收尾工作,保证事务的完整性,在经表修改之后才能生效*/
--行级触发器是对DML语句影响的每个行执行一次,如UPDATE语句影响多行,就会对每行都激活一次触发器。
-----创建
--创建只有一个执行语句的触发器
基本形式如下:
create
trigger
触发器名 before|
after
触发事件
--触发事件可以为insert,update,delete
on
表名
for
each row 执行语句
例:
create
trigger
dept_trig1 before
insert
on
department
for
each row
insert
into
trigger_time
values
(now());
--补坑,创建trigger_time表
drop
table
if exists tigger_time;
--拼错了,少了一个'r'
create
table
trigger_time(
exec_time
time
)
desc
trigger_time
--检查trigger效果
select
*
from
department;
insert
into
department
values
(1004,
'销售部'
,
'负责产品销售'
,
'1号楼销售大厅'
)
--报错,duplicate entry
desc
department
--d_name是唯一性约束,不能取名‘销售部’
insert
into
department
values
(1004,
'销售1部'
,
'负责产品销售'
,
'1号楼销售大厅'
)
select
table_schema
from
information_schema.tables
where
table_name=
'trigger_time'
--查看trigger_time表属于什么库
select
*
from
trigger_time
--查看trigger_time表是否被触发器更新,Ok
--创建有多个执行语句的触发器
基本形式如下
create
trigger
触发器名 before|
after
触发事件
--触发事件可以为insert,update,delete
on
表名
for
each row
--在指定表上逐行触发
begin
执行语句1;
执行语句2;
.........;
END
/*MySQL默认以
';'
最为整段执行语句结束标志,这里用delimiter &&进行转意成&&,&&表示整段语句结束,在IDE里面应该可以不用转意*/
例:
delimiter &&
create
trigger
dept_trigzz
after
delete
on
department
for
each row
begin
insert
into
trigger_time
values
(
'21:01:01'
);
insert
into
trigger_time
values
(
'22:01:01'
);
end
&&
delimiter;
show triggers
--检查trigger效果
delete
from
department
where
d_id=1004;
select
*
from
trigger_time
--成功insert,ok
/*一个表在相同触发时间的相同触发事件,只能创建一个触发器*/
/*如department表中,触发事件
Insert
,触发事件为
after
的触发器只能有一个,但可以定义触发事件为Before的触发器*/
---查看触发器
---1.show triggers
show triggers
--show triggers无法查询指定的触发器,只用于触发器较少的情况
---2.从triggers表中查看触发器信息
select
*
from
information_schema.triggers
where
tigger_name=
'触发器名'
---触发器的使用
--分别创建before insert和after insert两个触发器,比较执行顺序
--创建before insert触发器
create
trigger
before_insert before
insert
on
department
for
each row
insert
into
trigger_test
values
(
null
,
'before_insert'
);
--创建after insert触发器
create
trigger
after_insert
after
insert
on
department
for
each row
insert
into
trigger_test
values
(
null
,
'after_insert'
);
--补坑,创建trigger_test表
create
table
trigger_test(id
int
auto_increment
primary
key
,
info
varchar
(10)
);
--验证触发器
insert
into
department
values
(1004,
'销售1部'
,
'负责产品销售'
,
'1号楼销售大厅'
);
delete
from
department
where
id =
'1004'
desc
department
delete
from
department
where
d_id =
'1004'
insert
into
department
values
(1004,
'销售1部'
,
'负责产品销售'
,
'1号楼销售大厅'
);
--info字段报错,长度不够
--修改表中列的字段长度,
alter
table
trigger_test change
column
info info
varchar
(15);
--change可以同时改表字段名与数据类型,但只修改字段长度时需重复一遍字段名
alter
table
trigger_test
modify
column
info
varchar
(16);
--modify只可以更改字段数据类型
--删除产生错误的插入列
delete
from
department
where
d_id =
'1004'
--重新插入
insert
into
department
values
(1004,
'销售1部'
,
'负责产品销售'
,
'1号楼销售大厅'
);
--验证触发器执行结果
select
*
from
trigger_test
--第一条记录为before_insert触发器激活后插入的‘before_insert’,第二条记录为after_insert触发器激活后插入的‘after_insert’,ok
/*FBI warning*/
/*触发器中不能包含事物处理的关键词如:start
transaction
,
commit
,
rollback
,也不能包含call语句*/
/*在触发器执行过程中,任何步骤出错都会阻止程序继续向下执行,但对产生触发事件的普通表来说,已经
insert
/
delete
/
update
过的记录是不能回滚的,更新过的数据将继续保持在表中*/
---删除触发器
基本形式:
drop
trigger
触发器名
drop
trigger
数据库实例名.触发器名
--触发器是属于数据库实例全局的
例:
drop
trigger
dept_trig1
--查询是否还存在
select
*
from
information_schema.triggers
where
trigger_name=
'dept_trig'
--查询无结果,Ok
/*FBI warning*/
/*当不再需要某个触发器时,一定要将这个触发器删除,否则会造成数据发生意料之外的变化*/
|
本文转自 angry_frog 51CTO博客,原文链接:http://blog.51cto.com/l0vesql/1773648