it编程 > 数据库 > Mysql

MySQL游标和触发器的操作流程

9人参与 2025-12-08 Mysql

游标

使用select语句可以返回符合指定条件的结果集(虚拟表),但没有办法对结果集中的数据进行单独的处理。例如,使用select语句查询出多条员工信息的结果集后,无法获取结果集中的单条记录。为此,mysql提供了游标机制,利用游标可以对结果集中的数据进行单独处理

游标的操作流程

1. 定义游标

declare 游标名称 curson for select语句

特点:游标名称必须唯一,因为在存储过程和函数中可以存储多个游标,而游标名就是区分不同游标的唯一标志。另外select语句中不能含有into关键字。需要注意的是,变量、错误触发条件、错误处理程序和游标都是通过declare定义的,但他们的定义是有先后顺序要求的。变量和错误触发条件必须在最前面声明,然后是游标的声明,最后才是错误处理程序的声明。

2.打开游标

open游标名称

3.利用游标检索数据

fetch 游标名称 into 变量名1 [,变量名2]...

每执行一次fetch语句就在结果集中获取一行记录,fetch语句获取记录后,游标的内部指针就会向前移动一步,指向下一条记录。并将获取到的记录存入对应的变量中,其中变量名的个数要和select语句查询出来的结果集一致。

fetch语句一般和循环语句一起完成数据的检索,它通常和repeat循环语句一起使用。因为无法直接判断哪条记录是结果集中的最后一条记录,当利用游标从结果集中检索出最后一条记录后,再次执行fetch语句,将产生error 1329 (02000):no data to fetch错误信息。因此,使用游标时通常自定义错误处理程序处理该错误,从而结束游标的循环。

4.关闭游标

close 游标名称

在程序内,如果使用close关闭了游标,则不能再通过fetch使用该游标。如果想要再次利用游标检索数据,只需要使用open打开游标即可,而不用重新定义游标。如果没有使用close关闭游标,那么它将在被打开的begin...end语句块的末尾关闭。

例题

技术人员想将员工表emp中奖金为null的员工信息存放在一个新的数据表emp_comm中,数据表emp_comm的结构和员工表保持一致

原表如下

创建一个存储过程,实现将奖金为null的员工信息添加到数据表emp_comm

然后定义存储过程如下

delimiter // -- 修改mysql语句默认结束符号为//
create procedure proc_emp_comm() -- 创建名为proc_emp_comm()的存储过程
begin -- 开始存储过程
declare mark int default 0; -- 定义了变量mark用于存储游标结束循环的标识
# 定义变量用来存储select语句查询出来的8个字段数据
declare emp_no int;
declare emp_name varchar(20);
declare emp_job varchar(20);
declare emp_mgr int;
declare emp_hiredate date;
declare emp_sal decimal(7,2);
declare emp_comm decimal(7,2);
declare emp_deptno int;
declare cur cursor for select * from emp where comm is null; -- # 定义游标
declare continue handler for sqlstate '02000' -- 定义错误程序及处理方式
 set mark=1;
# 打开游标
open cur;
# 借助repeat循环,移动指针获取虚拟结果集中的数据,存储到定义的变量中
repeat -- 开启循环
fetch cur into emp_no,emp_name,emp_job,emp_mgr,emp_hiredate,emp_sal,emp_comm,emp_deptno; -- 使用上面定义的8个字段去接收查询语句查询出来的数据
if mark!=1 then -- 只要mark值不为1,说明结果集中还有数据,就将数据添加到emp_comm表中
 insert into emp_comm values(emp_no,emp_name,emp_job,emp_mgr,emp_hiredate,emp_sal,emp_comm,emp_deptno);
end if; -- 结束if语句
until mark=1 end repeat; -- 结束repeat循环语句
close cur; -- 关闭游标
end // -- 结束存储过程
delimiter ; -- 设置mysql命令结束符号为;
 

调用存储过程

call proc_emp_comm();

查看emp_comm表数据

select * from emp_comm;

触发器

在实际开发项目时,如果需要在数据表发生更改时自动进行一些处理,这时就可以使用触发器。

例如,删除一条数据时,需要在数据库中保留一个备份副本,这种情况下可以创建一个触发器对象,每当删除一条数据时,就执行一次备份操作。

触发器可以看成一种特殊的存储过程,它不用call语句调用,而是在预选定义好的操作自动调用(insert,delete)等

触发器具有以下优点

当触发器相关联的数据表中的数据发生修改时,触发器中定义的语句会自动执行。

触发器对数据进行安全校验,保障数据安全。

通过和触发器相关联的表,可以实现表数据的级联更改,在一定程度上保证数据的完整性。

触发器的基本操作

1.创建触发器

create trigger 触发器名称 触发时机 触发事件 on 数据表名 for each row 触发程序

2.查看触发器

show triggers;

利用select语句查看数据库information_schema下数据表trigges中的触发器数据

select * from information_schema.triggers [where trigger_name = '触发器名称'];

3. 触发触发器

根据定义的触发器知道,执行删除操作时,会触发触发器的执行(下面的例题)
delete from emp where empno=8888;

4. 删除触发器

drop trigger [if exists] [数据库名.]触发器名;-- delete一般删除表中数据,其他为drop

drop trigger if exists trig_emp;(下面例题)

例题

技术人员想要在删除员工信息后,自动将删除的员工信息添加在其他数据表,以防后续需要查询被删除的员工信息

 首先创建一个新的表,用来存储删除的数据,这个表的字段和emp表的字段一样

create table `emp_del` (
  `empno` int default null,
  `ename` varchar(50) default null,
  `job` varchar(50) default null,
  `mgr` int default null,
  `hiredate` date default null,
  `sal` decimal(7,2) default null,
  `comm` decimal(7,2) default null,
  `deptno` int default null
);

接着在员工表emp中创建触发器。当
删除员工表的数据后,触发该触发器,
并且在触发器的触发程序中将被删除的员工信息添加到数据表emp_del

# create trigger 触发器名称 触发时机 触发事件 on 数据表名 for each row 触发程序

delimiter //
create trigger trig_emp
after delete on emp
for each row
begin
    insert into emp_del(empno, ename, job, mgr, hiredate, sal, comm, deptno)
    values(old.empno, old.ename, old.job, old.mgr, old.hiredate, old.sal, old.comm, old.deptno);
end //
delimiter ;

接着根据定义的触发器知道,执行删除操作时,会触发触发器的执行

-- 删除员工编号为 8888 的记录
delete from emp where empno = 8888;
-- 删除员工编号为 7369 的记录
delete from emp where empno = 7369;

查看触发器

show triggers;

到此这篇关于mysql游标和触发器的操作流程的文章就介绍到这了,更多相关mysql游标和触发器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

MySql 游标和触发器概念及使用详解

12-08

MySQL回滚binlog日志的实现示例

12-08

使用 MySQL Workbench 进行高效数据库设计

12-08

解决Navicat导入DBF中文乱码的问题

12-08

MySQL实现读写分离架构的原理与实现方法

12-08

MySQL查看表的历史SQL的几种实现方法

12-08

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论