@
目录
前言
在完成了我们的MySQL的基础教程后,对数据库与表结构的基础操作有了基础概念后,我们继续对MySQL的特性进行学习。本次教程将聚焦与SQL语句来进行介绍,本期要介绍的是储存过程与触发器。
一、准备工作
(一)SQL语句分类型
在正式开始内容前,我们需要回顾一下SQL语句的分类,我们才能具体知道存储过程和触发器到底是一个怎么样的概念。其中SQL语句可分为以下几类。
- DDL【data definition language】 数据定义语言,用来维护存储数据的结构
代表指令: create, drop, alter - DML【data manipulation language】 数据操纵语言,用来对数据进行操作
代表指令: insert,delete,update
DML中又单独分了一个DQL,数据查询语言,代表指令: select - DCL【Data Control Language】 数据控制语言,主要负责权限管理和事务
代表指令: grant,revoke,commit
(二)Navicat工具
本次课程SQL语句的编写将借助Navicat这个工具,有兴趣的读者可以了解一下该工具的使用。
Navicat 是一款专业的图形化数据库管理和开发工具。它的核心价值在于,用一个直观的图形界面替代了复杂的命令行操作,让我们更方便的连接与管理各类数据库。
在这里,我们给出Navicat免费版本的Navicat Premium Lite的官网下载链接,有需要的友友可用。点此处去下载
二、存储过程
(一)定义与特性
存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字和参数来执行,并获取相应的结果。
其具有封装性、可维护性、可重复性的特点 。与用应用程序直接操作数据库的不同点可以用下图进行解释。
可见,其相当与一个经编译后存储在数据库里的媒介,替代应用程序去完成操作数据库的任务。
除了以上特性外,存储过程还有着以下优缺点。
优点:
- 性能优化:存储过程在创建时编译并存储在数据库中,执行速度比单个SQL语句快。
- 代码重用:存储过程可以重复调用,减少重复代码,提高代码的可维护性。
- 安全性:可以限制用户直接访问数据库,通过存储过程间接访问,从而保证系统安全性。
- 事务管理:可以在存储过程中实现复杂的事务逻辑。
- 降低耦合:当表结构发⽣变化时,只需要修改相应的存储过程,应用程序的改动较小。
缺点:
- 可移植性差:存储过程不能跨数据库移植,更换数据库时需要重新编写。
- 调试困难:只有少数数据库管理系统支持存储过程的调试,开发和维护困难。
- 不适合高并发场景:在高并发场景下,存储过程可能会增加数据库的压力,难以维护。
(二)相关语法
1、创建
sql
-- 修改SQL语句结束标识符为 //
DELIMITER //
-- 创建存储过程
CREATE PROCEDURE 存储过程名 (参数列表)
BEGIN
-- SQL 语句
END //
-- 修改SQL语句结束标识符为 ;
DELIMITER ;'
2、调用
sql
-- 调⽤存储过程
CALL 存储过程名 (参数列表);
3、查看
sql
-- 查看指定数据库中创建的存储过程
SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = '数据库名';
-- 查看存储过程的定义
SHOW CREATE PROCEDURE 存储过程名;
4、删除
sql
DROP PROCEDURE [IF EXISTS] 存储过程名;
下面给出使用的例子
sql
-- 计算学生们总分
-- 创建存储过程
DELIMITER //
DROP PROCEDURE IF EXISTS p1;
CREATE PROCEDURE IF NOT EXISTS p1()
BEGIN
select name,chinese + math + english as total from exam;
END //
DELIMITER ;
-- 调用存储过程
call p1();
其中的 DELIMITER // 是用来告诉客户端,接下来遇到 // 才认为一条完整语句结束。存储过程内部的 ; 不会被客户端当作语句结束符。其只在使用 mysql 命令行或支持该命令的客户端时需要,例如 mysql CLI、Navicat 的查询窗口。
三、变量
在MySQL中变量主要分为:系统变量、用户自定义变量和局部变量。
(一)系统变量
系统变量是MySQL服务器的配置变量,控制着服务器的行为和性能。分为全局变量(GLOBAL)和会话变量(SESSION) 。
1、查看环境变量
sql
-- 查看所有系统变量
SHOW [GLOBAL|SESSION] VARIABLES;
-- 查看指定的系统变量
SHOW [GLOBAL|SESSION] VARIABLES LIKE 'xxx';
-- 查看指定的系统变量,可以通过LKIE进⾏模糊查询
SHOW [GLOBAL|SESSION] VARIABLES like '%xxx%';
-- 使⽤SELECT查看指定系统变量
SELECT @@[GLOBAL|SESSION].系统变量名;
2、设置环境变量
sql
SET [GLOBAL|SESSION] 系统变量名 = 值;
SET @@SESSION.系统变量名 = 值;
值得注意的是:
如果在设定时没有指定GLOBAL|SESSION ,则默认设置为会话SESSION。
当会话关闭后,所设置的会话变量会失效,新建会话时读取全局系统变量来作为初始值。
当MySQL重启后,设置的全局变量就会失效,想要自己设置的全局变量永久生效,需要去修改对应的配置文件。
(二)用户自定义变量
用户自定义变量是在SQL会话中定义的变量,不用提前声明,其作用域为当前会话。
1、赋值
sql
-- ⽅式⼀
SET @var_name = expr [, @var_name]...;
-- ⽅式⼆ 【推荐】
SET @var_name := expr [, @var_name]...;
-- ⽅式三:在SELECT语句中
SELECT @var_name := expr [, @var_name]...;
-- ⽅式四:查询结果赋值给⾃定义变量
SELECT 列名 INTO @var_name FROM 表名 WHERE ...;
因为由于SQL中比较比较相等也是使用等号 (=),所以在为变量赋值的时候推荐使用 ( := ) 。
举一个例子:
sql
-- ⽰例:定义⼀个age变量并赋值为18,并查看
SET @age := 18;
SELECT @age;
-- ⽰例:从学⽣表中查询编号为1的学⽣学号并赋值给sno变量
SELECT sno INTO @sno from student where id = 1;
SELECT @sno;
-- ⽰例:查询学⽣表中的总记录数并赋值给conut变量
SELECT count(*) INTO @count from student;
SELECT @count;
-- ⽰例:访问⼀个未赋值的变量,返回NULL
SELECT @var;
(三)局部变量
局部变量只在存储过程、函数或触发器的范围内有效。需要使用 DECLARE 声明,使用的作用域的范围在声明的 BEGIN ... END 块内。
1、声明
DECLARE 变量名 变量类型 DEFAULT 默认值 ...;
2、赋值
sql
-- ⽅式⼀
SET var_name = 值;
-- ⽅式⼆ 【推荐】
SET var_name := 值;
-- ⽅式三:查询结果赋值给⾃定义变量
SELECT 列名 INTO var_name FROM 表名 WHERE ...;
具体使用的例子:
sql
-- ⽰例:在存储过程中定义局部变量记录学⽣表的总记录数
delimiter //
drop procedure if exists p2;
create procedure if not exists p2()
begin
declare stu_cnt int default 0;
select count(*) into stu_cnt from student;
select stu_cnt;
end //
delimiter ;
call p2();
要注意的是:
- 变量名不区分大小写
- 在存储过程和函数中,局部变量必须在使用前声明。
- 用户自定义变量在会话结束时失效,而局部变量在存储过程或函数结束时失效。
- 避免使用保留字作为变量名。
结语
以上便是本期关于MySQL储存过程与触发器章节的上部分内容了。如果喜欢我的内容,请点赞、收藏加关注,多多支持我,以及欢迎各位在评论区讨论交流,并指出我的不足,谢谢大家。