MySQL高阶---存储过程与函数、触发器、事务

发布时间:2023-05-24 19:30

存储过程与函数

1. 介绍

存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合。
1. 存储过程和函数的好处

  • 提高代码的复用性。
  • 减少数据在数据库和应用服务器之间的传输,提高效率
  • 减少代码层面的业务处理

2. 存储过程和函数的区别

  • 存储函数必须有返回值
  • 存储讨程可以没有返回值

2. 存储过程

1. 创建和调用

-- 修改结束分隔符为$
DELIMITER $
-- 创建存储过程
CREATE PROCEDURE 存储过程名称(参数列表)
BEGIN
   SQL 语句列表;
END$
-- 修改结束分隔符
DELIMITER ;

调用存储函数

CALL 存储过程名称(实际参数);
/*
	创建存储过程

	-- 修改分隔符为$
	DELIMITER $

	-- 标准语法
	CREATE PROCEDURE 存储过程名称(参数列表)
	BEGIN
		SQL 语句列表;
	END$

	-- 修改分隔符为分号
	DELIMITER ;
*/
-- 创建stu_group()存储过程,封装 分组查询总成绩,并按照总成绩升序排序的功能
DELIMITER $
CREATE PROCEDURE stu_group()
BEGIN
	SELECT gender,SUM(score) getSum FROM student GROUP BY gender ORDER BY getSum ASC;
END$

DELIMITER ;
/*
	调用存储过程
	CALL 存储过程名称(实际参数);
*/
-- 调用stu_group()存储过程
CALL stu_group();

2. 查看和删除 

查看数据库中所有的存储过程

SELECT * FROM mysql.proc WHERE db='数据库名称';

删除存储过程

DROP PROCEDURE [IF EXISTS] 存储过程名称;

3. 变量

定义变量

DECLARE 变量名 数据类型 [DEFAULT 默认值];

变量赋值方式一

SET 变量名 = 变量值;

变量赋值方式二

SELECT 列名 INTO 变量名 FROM 表名 [WHERE 条件];

4. if语句使用

标准语法:

IF 判断条件1 THEN 执行的sql语句1;
[ELSEIF 判断条件2 THEN 执行的sql语句2;]
...
[ELSE 执行的sql语句n;]
END IF;

5. 参数传递

存储过程的参数与返回值

CREATE PROCEDURE 存储过程名称([IN|OUT|INOUT] 参数名 数据类型)
BEGIN
   SQL 语句列表;
END$

IN:代表输入参数,需要由调用者传递实际数据(默认)

OUT:代表输出参数,该参数可以作为返回值

IOUT:代表既可以作为输入参数,也可以作为输出参数

/*
	参数传递
	CREATE PROCEDURE 存储过程名称([IN|OUT|INOUT] 参数名 数据类型)
	BEGIN
		SQL 语句列表;
	END$
*/
/*
	输入总成绩变量,代表学生总成绩
	输出分数描述变量,代表学生总成绩的描述信息
	根据总成绩判断:
		380分及以上  学习优秀
		320 ~ 380    学习不错
		320以下      学习一般
*/
DELIMITER $

CREATE PROCEDURE pro_test5(IN total INT,OUT info VARCHAR(10))
BEGIN
	-- 对总成绩判断
	IF total > 380 THEN
		SET info = '学习优秀';
	ELSEIF total >= 320 AND total <= 380 THEN
		SET info = '学习不错';
	ELSE
		SET info = '学习一般';
	END IF;
END$

DELIMITER ;

-- 调用pro_test5存储过程
CALL pro_test5(350,@info);

CALL pro_test5((SELECT SUM(score) FROM student),@info);

SELECT @info;

 6. while循环的使用

循环语法

初始化语句;
WHILE 条件判断语句 DO
   循环体语句;
   条件控制语句;
END WHILE;
/*
	while循环
	初始化语句;
	WHILE 条件判断语句 DO
		循环体语句;
		条件控制语句;
	END WHILE;
*/
-- 计算1~100之间的偶数和
DELIMITER $

CREATE PROCEDURE pro_test6()
BEGIN
	-- 定义求和变量
	DECLARE result INT DEFAULT 0;
	-- 定义初始化变量
	DECLARE num INT DEFAULT 1;
	-- while循环
	WHILE num <= 100 DO
		IF num % 2 = 0 THEN
			SET result = result + num;
		END IF;
		
		SET num = num + 1;
	END WHILE;
	
	-- 查询求和结果
	SELECT result;
END$

DELIMITER ;
-- 调用pro_test6存储过程
CALL pro_test6();

3. 存储函数

存储函数和存储过程非常相似,区别在于存储函数必须有返回值

创建存储函数

CREATE FUNCTION 函数名称([参数 数据类型])
RETURNS 返回值类型
BEGIN
   执行的sql语句;
   RETURN 结果;
END$

调用存储函数

SELECT 函数名称(实际参数);

删除存储函数

DROP FUNCTION 函数名称;
/*
	创建存储函数
	CREATE FUNCTION 函数名称([参数 数据类型])
	RETURNS 返回值类型
	BEGIN
		执行的sql语句;
		RETURN 结果;
	END$
*/
-- 定义存储函数,获取学生表中成绩大于95分的学生数量
DELIMITER $

CREATE FUNCTION fun_test1()
RETURNS INT
BEGIN
	-- 定义变量
	DECLARE s_count INT;
	-- 查询成绩大于95分的数量,为s_count赋值
	SELECT COUNT(*) INTO s_count FROM student WHERE score > 95;
	-- 返回统计结果
	RETURN s_count;
END$

DELIMITER ;
/*
	调用函数
	SELECT 函数名称(实际参数);
*/
-- 调用函数
SELECT fun_test1();
/*
	删除函数
	DROP FUNCTION 函数名称;
*/
-- 删除函数
DROP FUNCTION fun_test1;

触发器 

1. 介绍

  • 触发器是与表有关的数据库对象,可以在insert、update、delete之前或之后触发并执行触发器中定义的SQL语句。
  • 这种特性可以协助应用系统在数据库端确保数据的完整性、日志记录、数据校验等操作。
  • 使用别名NEW和OLD来引用触发器中发生变化的内容记录。

触发器分类

MySQL高阶---存储过程与函数、触发器、事务_第1张图片

 2. INSERT型触发器

 创建触发器

CREATE TRIGGER 触发器名称
BEFORE|AFTER INSERT|UPDATE|DELETE
ON 表名
FOR EACH ROW
BEGIN
   触发器要执行的功能;
END$
/*
	创建触发器
	DELIMITER $

	CREATE TRIGGER 触发器名称
	BEFORE|AFTER INSERT|UPDATE|DELETE
	ON 表名
	FOR EACH ROW
	BEGIN
		触发器要执行的功能;
	END$

	DELIMITER ;
*/
-- 创建INSERT型触发器。用于对account表新增数据进行日志的记录
DELIMITER $

CREATE TRIGGER account_insert
AFTER INSERT
ON account
FOR EACH ROW
BEGIN
	INSERT INTO account_log VALUES (NULL,'INSERT',NOW(),new.id,CONCAT('插入后{id=',new.id,',name=',new.name,',money=',new.money,'}'));
END$

DELIMITER ;

-- 向account表添加一条记录
INSERT INTO account VALUES (NULL,'王五',2000);
-- 查询account表
SELECT * FROM account;
-- 查询account_log表
SELECT * FROM account_log;

3. UPDATE型触发器

-- 创建UPDATE型触发器。用于对account表修改数据进行日志的记录
DELIMITER $

CREATE TRIGGER account_update
AFTER UPDATE
ON account
FOR EACH ROW
BEGIN
	INSERT INTO account_log VALUES (NULL,'UPDATE',NOW(),new.id,CONCAT('更新前{id=',old.id,',name=',old.name,',money=',old.money,'}','更新后{id=',new.id,',name=',new.name,',money=',new.money,'}'));
END$

DELIMITER ;
	
-- 修改account表中李四的金额为2000
UPDATE account SET money=2000 WHERE id=2;
-- 查询account表
SELECT * FROM account;
-- 查询account_log表
SELECT * FROM account_log;

4. DELETE型触发器

-- 创建DELETE型触发器。用于对account表删除数据进行日志的记录
DELIMITER $

CREATE TRIGGER account_delete
AFTER DELETE
ON account
FOR EACH ROW
BEGIN
	INSERT INTO account_log VALUES (NULL,'DELETE',NOW(),old.id,CONCAT('删除前{id=',old.id,',name=',old.name,',money=',old.money,'}'));
END$

DELIMITER ;

-- 删除account表中王五
DELETE FROM account WHERE id=3;
-- 查询account表
SELECT * FROM account;
-- 查询account_log表
SELECT * FROM account_log;

4. 查看和删除触发器

1. 查看触发器

SHOW TRIGGERS;

2. 删除触发器

DROP TRIGGER 触发器名称;

事务

1. 介绍

  • 事务:一条或多条SQL语句组成一个执行单元,其特点是
  • 单元中的每条SQL语句都相互依赖,形成一个整体。
  • 如果某条SQL语句执行失败或者出现错误,那么整个单元就会撤回到事务最初的状态。
  • 如果单元中所有的SQL语句都执行成功,则事务就顺利执行。这个单元要么同时成功要么同时失败。

2. 事务的操作

开启事务
        START TRANSACTION;
回滚事务
        ROLLBACK;
提交事务
        COMMIT;

-- 张三给李四转账500元
-- 开启事务
START TRANSACTION;
-- 1.张三账户-500
UPDATE account SET money=money-500 WHERE NAME='张三';
 出错了...
-- 2.李四账户+500
UPDATE account SET money=money+500 WHERE NAME='李四';
-- 回滚事务
ROLLBACK;
-- 提交事务
COMMIT;

这里“出错了”导致两个update都不能执行成功,这就是事务的特点,这个单元要么同时成功要么同时失败。 

3. 事务提交方式

事务提交方式的分类
        自动提交(MySQL默认)--1代表自动提交,0代表手动提交
        手动提交。
查看事务提交方式
        SELECT@@AUTOCOMMIT;
修改事务提交方式
        SET @@AUTOCOMMIT=数字;

4. 事务的四大特性(ACID)

原子性(Atomicity)
        原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。
        因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
一致性(Consistency)
        一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态。
        也就是说一个事务执行之前和执行之后都必须处于一致性状态。
隔离性(isolcation)
        隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务。
        不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
持久性(durability)
        持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的。
        即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。

5. 事务的隔离级别 

1. 介绍

多个客户端操作时,各个客户端的事务之间应该是隔离的,相互独立的,不受影响的。
而如果多个事务操作同一批数据时,就会产生不同的问题,我们需要设置不同的隔离级别来解决这些问题。

2. 隔离级别分类

MySQL高阶---存储过程与函数、触发器、事务_第2张图片

3. 引发的问题

MySQL高阶---存储过程与函数、触发器、事务_第3张图片

4. 查询和修改隔离级别

查询数据库隔离级别
SELECT@@TRANSACTION_ISOLATION;
修改数据库隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL 级别字符串;

5. 总结

MySQL高阶---存储过程与函数、触发器、事务_第4张图片

注意:隔离级别从小到大安全性越来越高,但是效率越来越低,所以不建议修改数据库默认的隔离级别。 

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号