MySQL基础笔记(6) - 游标&触发器&事务
游标&触发器&事务
1. 游标
定义:有时需要在检索出来的行中前进或后退一行/多行,这就是使用游标的原因。游标是一个被存储在Mysql服务器上的数据库查询,它是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或游览其中的数据。Mysql的游标只能用于存储过程和函数
注意:创建语句均只能在命令行窗口执行,请先在命令行登录并转到当前库,然后再粘贴进行操作
#1.创建游标
DELIMITER //
CREATE PROCEDURE processorders()
BEGIN
DECLARE ordernumbers CURSOR
FOR
SELECT order_num FROM orders;
END//
#2.开关游标
OPEN ordernumbers;
CLOSE ordernumbers;
#实例
DELIMITER //
CREATE PROCEDURE processorders()
BEGIN
-- 定义三个变量
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
DECLARE t DECIMAL(8,2);
DECLARE ordernumbers CURSOR
FOR
SELECT order_num FROM orders;
-- 当没有更多的行供repeat循环的时候,将done设置为1,停止循环
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
-- 创建ordertotals表
CREATE TABLE IF NOT EXISTS ordertotals
(order_num INT,total DECIMAL(8,2));
OPEN ordernumbers;
-- 循环直到done不为0时停止
REPEAT
-- 游标结合repeat查看表每一行并存入到变量o中
FETCH ordernumbers INTO o;
-- ordertotal是上一章中用来统计商品总价格的存储流程s
CALL ordertotal(o,1,t);
-- 将计算结果插入到新表ordertotals中
INSERT INTO ordertotals(order_num,total)
VALUES(o,t);
UNTIL done END REPEAT;
CLOSE ordernumbers;
END//
SELECT *
FROM ordertotals;
#本实例跨度较大,重在理解
2. 触发器
定义:触发器是Mysql响应DELETE,INSERT,UPDATE语句而自动执行的一条/一组Mysql语句
2.1 触发器的创建与删除
-
创建触发器
语法:
create trigger [触发器名] [触发时机] [触发器响应的活动] ON [触发器关联的表]
CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH ROW SELECT 'Product added' INTO @asd; #只有表才能支持触发器,视图不支持 #触发器按每个表每个事件每次地定义,每个表每个事件每次只允许拥有一个触发器。因此,每个表最多支持6个触发器(每条insert,update,delete前后)。单一触发器不能与多个事件或多个表关联 #Mysql 5之后不允许触发器直接返回值,这里将返回值储存到了变量asd中
-
删除触发器
DROP TRIGGER newproduct;
2.2 触发器的使用
-
INSERT触发器
- INSERT触发器代码内,可以引用一个名为NEW的虚拟表,可以由此访问那些被插入的行
- 在BEFORE INSERT触发器中,NEW中的值也可以被更新(允许更改被插入的值)
- 对于AUTO_INCREMENT列,NEW在INSERT执行前包含0,在执行后包含新的自动生成的值
#实例 #设置一个触发器,每当插入完成后,从new表中获得order_num的新数值,然后储存到asd中 CREATE TRIGGER neworder AFTER INSERT ON orders FOR EACH ROW SELECT new.order_num INTO @asd; INSERT INTO orders(order_date,cust_id) VALUES(NOW(),10001); SELECT @asd;
-
DELETE触发器
-
DELETE触发器代码内,可以引用一个名为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;
-
-
UPDATE触发器
- UPDATE触发器代码总,可以引用OLD的虚拟表访问UPDATE之前的值,引用NEW的虚拟表访问UPDATE后的值
- 在BEFORE UPDATE触发器中,NEW中的值可能也被更新
- OLD中的值全都是只读的,不能更新
#实例 #设置一个触发器,保证州名的缩写总是大写 CREATE TRIGGER updatevender BEFORE UPDATE ON vendors FOR EACH ROW SET NEW.vend_state = Upper(NEW,vend_state);
3. 事务
3.1 事务的使用
定义:事务是指一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。一个事务一旦执行失败,就会回滚到上一个步骤。(MyISAM引擎不支持事务处理,一般使用InnoDB引擎)
特性(ACID):
- 原子性:一个事务不可再分割,要么都执行要么都不执行
- 一致性:一个事务执行会使数据从一个一致状态切换到另一个一致状态
- 隔离性:一个事物的执行不受其它事务的干扰
- 持久性:一个事务一旦提交,则会永久的改变数据库的数据
事务的分类:
- 隐式事务:事务没有明显的开启和结束的标记(比如insert,update,delete语句)
- 显式事务:事务具有明显的开启和结束的标记(使用前必须设置自动提交功能为禁用)
#1.开启事务
SET autocommit=0;
START TRANSACTION;
#2.编写一组事务的语句
UPDATE account SET balance = 500;
UPDATE account SET balance = 1500;
#3.结束事务
COMMIT; #提交事务
#OR
ROLLBACK; #回滚
#4.savepoint的使用:savepoint一般搭配rollback使用,用于指定回滚的位置
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a; #设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a; #回滚到保存点
#在事务中,回滚可以对INSERT,UPDATE,DELETE生效,但是对CREATE,DROP,TRANSACTION无效
3.2 事务的隔离级别
事务的隔离级别/并发问题 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
read uncommitted | √ | √ | √ |
read committed | × | √ | √ |
repeatable read | × | × | √ |
serializable | × | × | × |
查看隔离级别:select @@tx_isolation;
设置隔离级别:set session|global transaction isolation level 隔离级别;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)