MySQL游标和触发器
游标
1、概念
- 游标是指一个“箭头”指向数据,指向哪个数据就操作哪个数据
2、使用游标
-- 创建存储过程
create procedure p_yb()
begin
declare empno integer;
declare ename varchar(256);
declare result varchar(4000) default '';
-- 定义游标cursor_emp,针对于select语句
declare cursor_emp cursor for select e.empno,e.ename from emp e;
-- 设置超限empno=null,循环终止条件,SQLSTATE为02000表示找不到数据了
declare continue handler for SQLSTATE '02000' set empno = null;
-- 打开游标
open cursor_emp;
-- 游标指向数据存入两个变量
fetch cursor_emp into empno,ename;
while(empno is not null) do
-- 拼接结果
set result =concat(result,'empno:',empno,'ename:',ename,';');
fetch cursor_emp into empno,ename;
end while;
-- 关闭游标
close cursor_emp;
select result;
end;
-- 调用存储过程
call p_yb();
触发器
1、简介
- 触发器与数据表关系密切,主要用于保护表中的数据。
- 特别是当有多个表具有一定的相互联系的时候,触发器能够让不同的表保持数据的一致性
- 在MySQL中,只有执行insert,update,delete操作时才能激活触发器
2、优缺点
- 优点
- 触发器的执行是自动的,当对触发器相关表的数据做出相应的修改后立即执行
- 触发器可以实施比foreign key约束,check 约束更为复杂的检查和操作
- 触发器可以实现表数据的级联更改,在一定程度上保证了数据的完整性
- 缺点
- 使用触发器实现的业务逻辑在出现问题时很难进行定位,特别是涉及到多个触发器的情况下,会使后期维护变得困难
- 大量使用触发器容易导致代码结构被打乱,增加了程序的复杂性
- 如果需要变动的数据量较大时,触发器的执行效率会非常低
3、类型
- insert触发器
- 在insert语句执行之前或之后响应的触发器
- 在insert触发器代码内,可引用一个名为new的虚拟表来访问被插入的行
- update触发器
- 在update触发器代码内,可引用一个名为new的虚拟表来访问更新的值
- 在update触发器代码内,可引用一个名为old的虚拟表来访问update语句执行前的值
- 在before update 触发器内,new中的值可能也被更新,即允许更改将要用于update语句中的值
- old中的值全部是只读的,不能被更新
- delete触发器
- 在delete触发器代码内,可以引用一个名为old的虚拟表来访问被删除的行
- old中的值全部是只读,不能被更新
- 对于事务性表,如果触发程序失败,以及由此导致的整个语句失败,那么该语句所执行的所有更改将回滚
- 对于非事务性表,则不能执行此类回滚,即使语句失败,失败之前所做的任何更改依然有效
4、使用
before触发器
-- 创建触发器,每次将新增薪资记录到一个局部变量中
create trigger tr_salsum
before insert on emp
for each row
set @sum=@sum+new.sal;
-- 查看触发器的作用
set @sum=0;
insert into 'emp' values('9999','xiaoming','CLERK','7782','1982-01-23','1300',null,'10');
select @sum
after触发器
-- 首先创建一张相同的表
create table dept_copy as select * from dept;
-- 向dept插入数据的时候,也会向复制表中插入数据
create trigger tr_chinaloc
after insert on dept
for each row
insert into dept_copy
values(new.deptno,new.dname,concat('china-',new.loc));
--测试
insert into dept values(88,'shop','sh');
5、查看
-
show triggers;
-
指定触发器
select * from information_schema.triggers where trigger_name='tr_chinaloc';
6、修改删除
-
修改触发器可以通过删除原触发器,再以相同的名称创建新的触发器
-
删除一个表的同时,也会自动删除该表上的触发器
-
触发器不能更新或覆盖,为了修改一个触发器,必须先删除它,再重新创建
-
drop trigger [if exists] [数据库名]<触发器名>
drop trigger if exists tr_chinaloc