day03——存储过程与存储函数

存储过程

基本概念

存储过程和存储函数 类似于 Java 当中的方法, 可以对多组 SQL语句,进行封装操作。从 MySQL5.0 版本开始, 支持存储过程和存储函数。

  • 存储函数和存储过程的区别(了解)
1.存储函数:必须有返回值。
2.存储过程:可以没有返回值,也可以拥有返回值。
  • 优点和缺点(了解)
1.优点:
	A.存储过程可以封装 复杂的SQL语句,简化SQL的编写
	B.存储过程可以回传递增,并接受参数
	C.存储过程无法使用select指定来运行,与查看表数据或定义函数不同
	D.存储过程可以用在数据校验,强制实行商业逻辑等。
	
2.缺点:
	A.存储过程,往往制定在特定的数据库中,因为支持的编程语言不同,当切换其他厂商数据库时候,需要重写原有的存储过程。
	
	B.存储过程性能调校与撰写,受限于种种数据库系统。

准备数据

-- 删除数据库 db7
DROP DATABASE IF EXISTS db7;

-- 创建db7数据库
CREATE DATABASE IF NOT EXISTS db7 CHARACTER SET utf8;

-- 使用数据库
USE  db7;

-- 删除表数据
DROP TABLE IF EXISTS student;

-- 创建学生 student 表
CREATE TABLE IF NOT EXISTS student(
	id INT,  -- 学生id
	name VARCHAR(30),	-- 学生姓名
	age INT, -- 学生年龄
	gender VARCHAR(20),  -- 学生性别
	score INT  -- 考试成绩
);

-- 添加数据
INSERT INTO  student VALUES (1,'张三',23,'男',95),(2,'李四',24,'男',98),(3,'王五',24,'女',100),(4,'赵六',26,'女',90);

-- 查看结果
SELECT * FROM student;

-- 按照性别进行分组,查看每组学生的总成绩. 按照总成绩的升序排列
SELECT gender,SUM(score) '总分' FROM student GROUP BY gender ORDER BY '总分' ASC;

创建存储过程

  • 语法
-- 修改结束分隔符
DELIMITER $

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

-- 修改结束分隔符(⚠️警告:一定要打空格)
DELIMITER ;
  • 举例
-- 修改结束分隔符
DELIMITER $

-- 创建存储过程
CREATE PROCEDURE stu_group ()
BEGIN
	SELECT gender,SUM(score) FROM student GROUP BY gender;
END $

-- 修改结束分隔符
DELIMITER ;

调用存储过程

  • 语法
-- 调用存储过程
CALL  存储过程名称(实际参数);
  • 举例
-- 案例代码:调用存储过程
call stu_group();

查看存储过程

  • 语法
-- 查看存储过程(语法)
SELECT * FROM mysql.proc WHERE db = '数据库名称';
  • 举例
-- 案例代码: 查看存储过程
SELECT * FROM mysql.proc WHERE db = 'db7';

删除存储过程

  • 语法
-- 删除存储过程(语法)
DROP PROCEDURE IF EXISTS 存储过程名称;
  • 举例
-- 案例代码: 删除存储过程
DROP PROCEDURE IF EXISTS stu_group;

存储过程 变量使用

  • 创建存储过程,并定义变量
-- 修改结束符
delimiter $

-- 创建存储过程
create procedure stu_getsum()

-- 开始
begin
	-- 定义变量total,默认值10
	declare total int default 10;
	-- 修改变量total的值
	set total=20;
	-- 查询student表的总分,赋值给变量total
	select sum(score) into total from student;
	-- 查询total的结果
	select total;
-- 结束
end $

-- 修改结束符(⚠️警告:一定要打空格)
delimiter ;
  • 调用存储过程
call stu_getsum();

存储过程 if语句

  • 语法
IF  判断条件  THEN  条件满足需要执行的语句;
ELSEIF  判断条件  THEN  条件满足需要执行的语句;
ELSE  其他情况下需要执行的语句;
END IF;
  • 举例
需求:
    1. 定义一个 int 类型的变量,用于存储班级的总成绩
    2. 定义一个 varchar 类型的变量,用于存储分数的描述
    3. 根据总成绩,进行判断
	380分以上:  学习优秀
	320-380分:  学习不错
	320分以下:  学习一般

-- 创建存储过程
DELIMITER $

CREATE PROCEDURE stu_if()
BEGIN
    -- 定义变量,接收结果,查询总成绩赋值。
    DECLARE message VARCHAR(10); 
    DECLARE total INT;
    
    SELECT SUM(score) INTO total FROM student;
    IF total > 380 THEN SET message = '学习优秀';
    ELSEIF total >= 320 AND total <= 380 THEN SET message = '学习不错';
    ELSE SET message = '学习一般';
    END IF;
    -- 查询总成绩和描述信息
    SELECT total,message;
    
END $
DELIMITER ;

-- 第03步:调用存储过程
CALL stu_if();

存储过程 参数传递

  • 语法
CREATE  PROCEDURE  存储过程的名称([IN][OUT][INOUT]  参数名称  参数类型)
BEGIN 
		SQL语句列表;
END $
  • 举例
-- 第01步: 删除存储过程
DROP PROCEDURE IF EXISTS stu_param;

-- 第02步: 创建存储过程,设置为参数传递
DELIMITER $
CREATE PROCEDURE stu_param(IN total INT,INOUT message VARCHAR(20))
BEGIN
	IF total>380 THEN SET message = '学习优秀';
	ELSEIF total>=320 AND total<=380 THEN SET message = '学习不错';
	ELSE SET message = '学习一般';
	END IF;
END $
DELIMITER ;

-- 第03步: 调用存储过程
CALL stu_param(350,@message);

-- 第04步: 查询返回结果
SELECT @message;

存储过程 循环

  • 语法
初始化语句;
WHILE  	条件判断语句 DO
		循环体语句;
		条件控制语句;
END  WHILE;
  • 举例
-- 第01步:删除存储过程
DROP PROCEDURE IF EXISTS stu_loop;

-- 第02步:创建存储过程,计算 1-100 之间的偶数和
DELIMITER $

CREATE PROCEDURE stu_loop()
BEGIN
    DECLARE result INT DEFAULT 0;
    DECLARE num INT DEFAULT 1;
    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 ;

-- 第03步: 调用存储过程
CALL stu_loop();

存储函数

存储函数和存储过程理解上是一样的,只是存储函数有返回值,必须写return语句。

无参数的存储函数

  • 创建存储函数格式
DELIMITER $
CREATE  FUNCTION  函数名称(参数列表)  RETURNS 返回值类型
BEGIN
	SQL 语句列表;
	RETURN  结果;
END $
DELIMITER ;
  • 创建存储函数举例
-- 查询学生表当中,成绩大于 95分的学生人数。

-- 第01步: 删除存储函数
DROP FUNCTION IF EXISTS stu_hanshu;

-- 第02步: 创建存储函数
DELIMITER $
CREATE FUNCTION  stu_hanshu()  RETURNS INT
BEGIN 
	-- 定义变量,记录查询结果,返回
	DECLARE total INT;
	-- 获取到查询的结果
	SELECT COUNT(*) INTO total FROM student WHERE score>95;
	-- 返回结果
	RETURN total;
END $
DELIMITER ;

-- 第03步: 调用存储函数
SELECT stu_hanshu();

有参数的存储函数

-- 查询学生表当中,成绩大于 95分的学生人数。

-- 第01步: 删除存储函数
DROP FUNCTION IF EXISTS stu_hanshu;

-- 第02步: 创建存储函数
DELIMITER $
CREATE FUNCTION  stu_hanshu()  RETURNS INT
BEGIN 
	-- 定义变量,记录查询结果,返回
	DECLARE total INT;
	-- 获取到查询的结果
	SELECT COUNT(*) INTO total FROM student WHERE score>95;
	-- 返回结果
	RETURN total;
END $
DELIMITER ;

-- 第03步: 调用存储函数
SELECT stu_hanshu();

触发器

触发器就是在表数据发生变化的时候,自动触发的一些 SQL 操作。

触发器分类

触发器类型OLD 触发器之前的效果NEW 触发器之后的效果
INSERT 类型的触发器无(因为插入前,没有之前的数据)NEW 表示将要或者已经新增的数据
UPDATE 类型的触发器OLD 表示修改之前的数据NEW 表示将要或者已经修改后的数据
DELETE 类型的触发器OLD 表示将要或者已经修改的数据无(因为删除后,状态无数据)

准备数据

-- 删除数据库
DROP DATABASE IF EXISTS db8;

-- 创建数据库 db8
CREATE DATABASE IF NOT EXISTS db8 CHARSET utf8;

-- 使用数据库
USE db8;

-- 创建账户表
CREATE TABLE IF NOT EXISTS account(
	id INT PRIMARY KEY AUTO_INCREMENT,  -- 账户id
	NAME VARCHAR(20),  	-- 姓名
	money DOUBLE		-- 余额
);

-- 添加数据
INSERT INTO account VALUES (NULL,'张三',1000),(NULL,'李四',1000);

-- 创建日志表 account_log
CREATE TABLE IF NOT EXISTS account_log(
	id INT PRIMARY KEY AUTO_INCREMENT,  -- 日志id
	operation VARCHAR(20),  	-- 操作的类型(insert update delete)
	operation_time DATETIME, 	-- 操作时间
	operation_id INT,		-- 操作表的id
	operation_params VARCHAR(200)	-- 操作参数
);

INSERT 触发器

基础语法

-- 删除触发器
DROP TRIGGER IF EXISTS 触发器的名称;

-- 第02步,创建触发器
DELIMITER $

CREATE TRIGGER  触发器的名称  
AFTER INSERT ON 需要监测的表名称  FOR EACH ROW 
BEGIN
	INSERT INTO 记录结果的表名称 VALUES (1,2,3,4);
END $

DELIMITER ;

代码举例

-- 创建 INSERT 类型的触发器
-- 第01步,删除触发器
DROP TRIGGER IF EXISTS account_insert;

-- 第02步,创建触发器
DELIMITER $

CREATE TRIGGER account_insert  
AFTER INSERT ON account FOR EACH ROW 
BEGIN
	INSERT INTO account_log VALUES (
		NULL,
		'INSERT',
		NOW(),     -- 使用NOW函数,获取到当前的系统时间
		new.id,
		CONCAT('插入后{id=',new.id,'name=',new.name,'money=',new.money,'}')
	);
END $

DELIMITER ;

-- 第03步,向 account 表当中添加一条记录
INSERT INTO account VALUES (NULL,'王五',2000);

-- 第04步, 查询 account 表记录
SELECT * FROM account;

-- 第05步, 查询 account_log 表记录
SELECT * FROM account_log;

UPDATE 触发器

基础语法

-- 创建触发器, 创建更新的触发器 
DELIMITER $

CREATE TRIGGER  触发器的名称  
AFTER UPDATE ON  需要监测的表名称 FOR EACH ROW 
BEGIN
	INSERT INTO 记录结果的表名称 VALUES (1,2,3,4);
END $

DELIMITER ;

代码实现

-- 创建 UPDATE 类型的触发器

-- 第01步,删除触发器
DROP TRIGGER IF EXISTS account_update;

-- 第02步,创建触发器
DELIMITER $

CREATE TRIGGER account_update  
AFTER UPDATE ON account FOR EACH ROW 
BEGIN
	INSERT INTO account_log VALUES (
		NULL,
		'UPDATE',
		NOW(),     -- 使用NOW函数,获取到当前的系统时间
		new.id,
		CONCAT('更新前{id=',old.id,'name=',old.name,'money=',old.money,'}',
		'更新后{id=',new.id,'name=',new.name,'money=',new.money,'}')
	);
END $

DELIMITER ;

-- 第03步,向 account 表当中更新一条记录
UPDATE account SET money = money+10000 WHERE id = 1;

-- 第04步, 查询 account 表记录
SELECT * FROM account;

-- 第05步, 查询 account_log 表记录
SELECT * FROM account_log;

DELETE 触发器

基础语法

-- 创建触发器, 创建删除的触发器 
DELIMITER $

CREATE TRIGGER 触发器的名称
AFTER DELETE ON 需要监测的表名称 FOR EACH ROW 
BEGIN
	INSERT INTO 记录结果的表名称 VALUES (1,2,3,4);
END $

DELIMITER ;

代码实现

-- 创建 DELETE 类型的触发器
 
-- 第01步,删除触发器
DROP TRIGGER IF EXISTS account_delete;

-- 第02步,创建触发器
DELIMITER $

CREATE TRIGGER account_delete
AFTER DELETE ON account FOR EACH ROW 
BEGIN
	INSERT INTO account_log VALUES (
		NULL,
		'DELETE',
		NOW(),     -- 使用NOW函数,获取到当前的系统时间
		old.id,
		CONCAT('删除前{id=',old.id,'name=',old.name,'money=',old.money,'}')
	);
END $

DELIMITER ;

-- 第03步,向 account 表当中删除一条记录
DELETE FROM account WHERE id = 2;

-- 第04步, 查询 account 表记录
SELECT * FROM account;

-- 第05步, 查询 account_log 表记录
SELECT * FROM account_log;

查看和删除触发器

-- 1. 查看触发器
SHOW  TRIGGERS;

-- 2. 删除触发器
DROP  TRIGGER  触发器的名称;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值