软件设计之MySQL(8)

软件设计之MySQL(8)

此篇应在JavaSE之后进行学习:
路线图推荐:
【Java学习路线-极速版】【Java架构师技术图谱】
Navicat可以在软件管家下载
``
使用navicat连接mysql数据库创建数据库、表、转储sql文件,导入sql数据
MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板
资料可以去尚硅谷官网免费领取

学习内容:

  1. 变量
  2. 程序出错处理机制
  3. 流程控制
  4. 游标

1、变量

在 MySQL 数据库中,变量分为系统变量以及 用户自定义变量

系统变量

1、系统变量分为全局系统变量(需要添加 global 关键字)以及会话系统变量(需要添加 session 关键字),有时也把全局系统变量简称为全局变量,把会话系统变量称为local变量。如果不写,默认会话级别静态变量(在 MySQL 服务实例运行期间它们的值不能使用 set 动态修改)属于特殊的全局系统变量。
2、全局系统变量针对于所有会话(连接)有效,但不能跨重启,重启就是再重新创建一个新的MySQL实例了
3、会话系统变量仅针对于当前会话(连接)有效。会话期间,当前会话对某个会话系统变量值的修改,不会影响其他会话同一个会话系统变量的值

查看系统变量
(1)查看所有或部分系统变量
#查看所有全局变量
SHOW GLOBAL VARIABLES;
#查看所有会话变量
SHOW SESSION VARIABLES;SHOW VARIABLES;
#查看满足条件的部分系统变量。
SHOW GLOBAL VARIABLES LIKE '%标识符%';
#查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%标识符%';
(2)查看指定系统变量

作为 MySQL 编码规范,MySQL 中的系统变量以 两个“@” 开头,其中“@@global”仅用于标记全局系统变量,“@@session”仅用于标记会话系统变量。“@@”首先标记会话系统变量,如果会话系统变量不存在,则标记全局系统变量

#查看指定的系统变量的值
SELECT @@global.变量名;
#查看指定的会话变量的值
SELECT @@session.变量名;
#或者
SELECT @@变量名;
修改系统变量

有些时候,数据库管理员需要修改系统变量的默认值,以便修改当前会话或者MySQL服务实例的属性、特征。具体方法:
方式1:修改MySQL 配置文件 ,继而修改MySQL系统变量的值(该方法需要重启MySQL服务)
方式2:在MySQL服务运行期间,使用“set”命令重新设置系统变量的值
说明:
1、SET 全局系统变量:只针对于当前数据库实例有效,一旦重启mysql服务,就失效
2、SET 会话系统变量:只针对于当前会话有效,一旦结束会话,重新建立新的会话,就失效

SET @@global.变量名=变量值;
#方式2:
SET GLOBAL 变量名=变量值;
#为某个会话变量赋值
#方式1:
SET @@session.变量名=变量值;
#方式2:
SET SESSION 变量名=变量值;
用户变量

1、 用户变量是用户自己定义的,作为 MySQL 编码规范,MySQL 中的用户变量以== 一个“@” ==开头。根据作用范围不同,又分为 会话用户变量局部变量
2、会话用户变量:作用域和会话变量一样,只对 当前连接 会话有效。
3、局部变量:只在 BEGIN 和 END 语句块中有效。局部变量只能在 存储过程和函数 中使用。
在这里插入图片描述

会话用户变量
#变量的定义
#方式1:“=”或“:=”
SET @用户变量 =;
SET @用户变量 :=;
#方式2:“:=” 或 INTO关键字
SELECT @用户变量 := 表达式 [FROM 等子句];
SELECT 表达式 INTO @用户变量 [FROM 等子句];
#查看用户变量的值 (查看、比较、运算等)
SELECT @用户变量
局部变量

局部变量的声明只能放在 BEGIN … END 中,而且只能放在第一句

BEGIN
#声明局部变量
DECLARE 变量名1 变量数据类型 [DEFAULT 变量默认值];
DECLARE 变量名2,变量名3,... 变量数据类型 [DEFAULT 变量默认值];
#为局部变量赋值
SET 变量名1 =;
#SET 变量名1 := 值;
SELECTINTO 变量名2 [FROM 子句];
#查看局部变量的值
SELECT 变量1,变量2,变量3;
END

2、程序出错处理机制

定义条件 是事先定义程序执行过程中可能遇到的问题
处理程序 定义了在遇到问题时应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行

定义条件

将一个 错误名字 和 指定的错误条件 关联起来

DECLARE 错误名称 CONDITION FOR 错误码(或错误条件)
错误码

1、MySQL_error_codesqlstate_value 都可以表示MySQL的错误。
2、MySQL_error_code是数值类型错误代码。
3、sqlstate_value是长度为5的字符串类型错误代码
例如:在ERROR 1418 (HY000)中,1418是MySQL_error_code,'HY000’是sqlstate_value

#使用MySQL_error_code
DECLARE Field_Not_Be_NULL CONDITION FOR 1048;
#使用sqlstate_value
DECLARE Field_Not_Be_NULL CONDITION FOR SQLSTATE '23000';
定义处理程序

可以为SQL执行过程中发生的某种类型的错误定义特殊的处理程序

DECLARE 处理方式 HANDLER FOR 错误类型 处理语句
处理方式

在这里插入图片描述

错误类型

在这里插入图片描述

处理语句

在这里插入图片描述

#方法1:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info = 'NO_SUCH_TABLE';
#方法2:捕获mysql_error_value
DECLARE CONTINUE HANDLER FOR 1146 SET @info = 'NO_SUCH_TABLE';
#方法3:先定义条件,再调用
DECLARE no_such_table CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info = 'NO_SUCH_TABLE';
#方法4:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info = 'ERROR';
#方法5:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info = 'NO_SUCH_TABLE';
#方法6:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = 'ERROR';

3、流程控制

流程控制语句的作用就是控制存储过程中 SQL 语句的执行顺序
流程分为三大类:顺序结构,分支结构,循环结构
针对MySQL主要有三类[只能用于存储程序]
1、条件判断语句 :IF 语句和 CASE 语句
2、循环语句 :LOOP、WHILE 和 REPEAT 语句
3、跳转语句 :ITERATE 和 LEAVE 语句

分支结构之 IF
IF 表达式1 THEN 操作1
[ELSEIF 表达式2 THEN 操作2]……
[ELSE 操作N]
END IF
分支结构之 CASE
#情况一:类似于switch
CASE 表达式
WHEN1 THEN 结果1或语句1(如果是语句,需要加分号)
WHEN2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)

#情况二:类似于多重if
CASE
WHEN 条件1 THEN 结果1或语句1(如果是语句,需要加分号)
WHEN 条件2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)

CASE 练习题

声明存储过程“update_salary_by_eid4”,定义IN参数emp_id,输入员工编号。判断该员工薪资如果低于9000元,就更新薪资为9000元;薪资大于等于9000元且低于10000的,但是奖金比例为NULL的,就更新奖金比例为0.01;其他的涨薪100元

CREATE PROCEDURE update_salary_by_eud4(IN emp_id INT)
BEGIN	
			#局部变量声明
			DECLARE  emp_sal DOUBLE ;
			DECLARE bonus DOUBLE;
			#局部变量赋值
			SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id;
			SELECT commission_pct INTO bonus FROM employees WHERE employee_id = emp_id;
			CASE
			WHEN emp_sal < 9000 THEN  UPDATE employees SET salary = 9000 WHERE employee_id = emp_id;
			WHEN emp_sal < 10000 AND bonus IS NULL THEN UPDATE employees SET commission_pct = 0.01 WHERE employee_id = emp_id;
			ELSE UPDATE employees SET salary = salary+100 WHERE employee_id = emp_id;
		  END CASE;
			
 END
循环结构之LOOP

LOOP循环语句用来重复执行某些语句。LOOP内的语句一直重复执行直到循环被退出(使用LEAVE子句),跳出循环过程。
循环对应四个要素:初始化条件循环条件循环体迭代条件

#loop_label是自己取的标签名
[loop_label:]LOOP
	循环执行语句
END LOOP [loop_label]
LOOP练习题

当市场环境变好时,公司为了奖励大家,决定给大家涨工资。声明存储过程
“update_salary_loop()”,声明OUT参数num,输出循环次数。存储过程中实现循环给大家涨薪,薪资涨为原来的1.1倍。直到全公司的平均薪资达到12000结束。并统计循环次数。

CREATE PROCEDURE update_salary_loop(OUT num INT)
BEGIN
			#创建局部变量
			DECLARE salary_avg DOUBLE ;#记录平均工资
			DECLARE loop_count INT DEFAULT 0;#记录循环次数
			#初始化条件
 			#赋值局部变量
			SELECT AVG(salary) INTO salary_avg FROM employees;
			loop_lab:LOOP
			#循环条件
			#结束循环条件
			IF salary_avg >= 12000	THEN LEAVE loop_lab;
			END IF;
			#循环体
			#如果低于12000
			UPDATE employees SET salary = salary * 1.1;
			#迭代条件
			#更新salary_avg!!
			SELECT AVG(salary) INTO salary_avg FROM employees;
			#记录循环次数
			SET loop_count = loop_count + 1;
			END LOOP loop_lab;
			#给num赋值
			SET num = loop_count;
END
循环结构之WHILE

WHILE语句创建一个带条件判断的循环过程。WHILE在执行语句执行时,先对指定的表达式进行判断,如果为真,就执行循环内的语句,否则退出循环。

[while_label:] WHILE 循环条件 DO
循环体
END WHILE [while_label];
循环结构之REPEAT

REPEAT语句创建一个带条件判断的循环过程。与WHILE循环不同的是,REPEAT 循环首先会执行一次循环,然后在 UNTIL 中进行表达式的判断,如果满足条件就退出,即END REPEAT;如果条件不满足,则会就继续执行循环,直到满足退出条件为止。

[repeat_label:] REPEAT
循环体的语句
UNTIL 结束循环的条件表达式   #(这里没分号)
END REPEAT [repeat_label]
跳转语句之LEAVE

LEAVE语句:可以用在循环语句内,或者以 BEGIN 和 END 包裹起来的程序体内,表示跳出循环或者跳出程序体的操作(类似JAVA:break)

LEAVE 标记名
LEAVE练习题

创建存储过程 “leave_begin()”,声明INT类型的IN参数num。给BEGIN…END加标记名,并在BEGIN…END中使用IF语句判断num参数的值。
如果num<=0,则使用LEAVE语句退出BEGIN…END;
如果num=1,则查询“employees”表的平均薪资;
如果num=2,则查询“employees”表的最低薪资;
如果num>2,则查询“employees”表的最高薪资。
IF语句结束后查询“employees”表的总人数

CREATE PROCEDURE leave_begin(IN num INT)
begin_label: BEGIN
			IF num<=0
			THEN LEAVE begin_label;
			ELSEIF num=1
			THEN SELECT AVG(salary) FROM employees;
			ELSEIF num=2
			THEN SELECT MIN(salary) FROM employees;
			ELSE
			SELECT MAX(salary) FROM employees;
			END IF;
			#Navicat中显示问题:显示不了,命令行操作可以显示两个select语句
			SELECT COUNT(*) FROM employees;
END 
跳转语句之ITERATE

ITERATE语句:只能用在循环语句(LOOP、REPEAT和WHILE语句)内,表示重新开始循环,将执行顺序转到语句段开头处。 (类似JAVA:break)

ITERATE label
ITERATE练习题

定义局部变量num,初始值为0。循环结构中执行num + 1操作。
如果num < 10,则继续执行循环;
如果num > 15,则退出循环结构;

CREATE PROCEDURE iterate_test(IN num INT)
BEGIN 
		DECLARE num INT DEFAULT 0 ;
		my_loop :LOOP
			SET num = num + 1;
			IF num <10
					THEN ITERATE my_loop;
			ELSEIF num>15
					THEN LEAVE my_loop;
			END IF ;
		END LOOP;
END

4、游标

游标让我们能够对结果集中的每一条记录进行定位,并对指向的记录中的数据进行操作的数据结构。游标让 SQL 这种面向集合的语言有了面向过程开发的能力。
在 SQL 中,游标是一种临时的数据库对象,可以指向存储在数据库表中的数据行指针。这里游标充当了指针的作用,我们可以通过操作游标来对数据行进行操作。

第一步 声明游标

游标必须在声明处理程序之前被声明,并且变量和条件还必须在声明游标或处理程序之前被声明
要使用 SELECT 语句来获取数据结果集,而此时还没有开始遍历数据,这里select_statement 代表的是SELECT 语句,返回一个用于创建游标的结果集

#这个语法适用于 MySQL,SQL Server,DB2 和 MariaDB
DECLARE cursor_name CURSOR FOR select_statement;
#如果是用 Oracle 或者 PostgreSQL,需要写成
DECLARE cursor_name CURSOR IS select_statement;
第二步 打开游标

当我们定义好游标之后,如果想要使用游标,必须先打开游标。打开游标的时候 SELECT 语句的查询结果集就会送到游标工作区,为后面游标的 逐条读取 结果集中的记录做准备

OPEN cursor_name
第三步 使用游标(从游标中取得数据)

游标的查询结果集中的字段数,必须跟 INTO 后面的变量数一致,否则,在存储过程执行的时候,MySQL 会提示错误

#此处的var_name是声明游标前就定义好的变量
#在声明游标中,从SELECT语句中选择了几个字段,此处就应该设置几个变量(var_name1,var_name2...)
FETCH cursor_name INTO var_name [, var_name] ...
第四步 关闭游标

游标会占用系统资源 ,如果不及时关闭,游标会一直保持到存储过程结束,影响系统运行的效率。

CLOSE cursor_name
游标练习题

创建存储过程“get_count_by_limit_total_salary()”,声明IN参数 limit_total_salary,DOUBLE类型;声明OUT参数total_count,INT类型。函数的功能可以实现累加薪资最高的几个员工的薪资值,直到薪资总和达到limit_total_salary参数的值,返回累加的人数给total_count。

CREATE PROCEDURE get_count_by_limit_total_salary(IN limit_total_salary DOUBLE,OUT total_count INT)
BEGIN
			#声明局部变量
			DECLARE sum_sal DOUBLE DEFAULT 0.0;#记录累加的工资总额
			DECLARE emp_sal DOUBLE;#记录每一个员工的工资
			DECLARE emp_count INT DEFAULT 0; #记录累加的人数
			#声明游标
			DECLARE emp_cursor CURSOR FOR SELECT salary FROM employees ORDER BY  salary DESC;
			#打开游标
			OPEN emp_cursor;
			loop_lab:LOOP
					IF sum_sal >= limit_total_salary
					THEN LEAVE loop_lab;
					END IF;
					#使用游标
					FETCH emp_cursor INTO emp_sal;
					SET sum_sal = sum_sal + emp_sal;
					SET emp_count = emp_count + 1;
			END LOOP loop_lab;
			SET total_count = emp_count;
			CLOSE emp_cursor;
END
CALL  get_count_by_limit_total_salary(200000,@total_count)
SELECT @total_count
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值