(八)MySQL事务、视图、变量、存储过程、函数、流程控制结构
补充:增删查改语句在数据库中基本通用,但这篇博客的内容基本是MySQL区别于其它数据库管理系统的知识,也要认真学习。
一、事务
1、含义:在MySQL中,可以通过创建事务来解决一些问题。
2、语法:
#1、开启事务
set autocommit=0; #禁用自动提交功能
#2、编写事务的sql语句
select insert update delete...
#3、结束事务
commit;提交事务
rollback;回滚事务
注意:MySQL默认提交事务,所以要先将autocommit功能禁用。
案例1:模拟张飞给刘备转账这一事件
查询数据库:
模拟转账:
SET AUTOCOMMIT=0;
UPDATE bank b
SET b.money=b.money-500
WHERE b.name='张飞';
UPDATE bank b
SET b.money=b.money+500
WHERE b.name='刘备';
转账后结果:
重新打开一个新标签,重新查询bank表中的内容:
可以看出数据库中的数据并未改变,因为前一个标签修改后还没有提交。
输入rollback,在第一个标签中再次查看表中数据:
可以看出rollback的作用是将数据恢复到上次提交之后的数据库内容。
案例2:savepoint 设置保存点
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;
DELETE FROM account WHERE id=28;
ROLLBACK TO a;
注意:保存点一定要起别名,便于和rollback搭配使用。
3、事务的隔离级别
脏读 不可重复读 幻读
read uncommitted: √ √ √
read committed: × √ √
repeatable read: × × √
serializable: × × ×
注意:
①mysql中默认 第三个隔离级别 repeatable read
②查看隔离级别:select @@tx_isolation;
③设置隔离级别:set session|global transaction isolation level 隔离级别;
4、各名词含义:
①脏读:其他人看到了更改的数据后,数据被滚回
②不可重复读:数据被滚回之后再次读取数值不同
③幻读:第一次查询数据为三条,在查询后数据条数被其他人更改,再次查询时数据条数与之前不同
二、视图
1、含义:视图是虚拟创建的表,不在库中真实存在,一般是将多个表中的数据合并在一个表中,便于以后直接对其操作。
2、创建视图:
案例:查询张姓学生的学生名和专业名
step1:新建视图v1,并将学生名和专业名存放在其中
CREATE VIEW v1 #先创建视图
AS
SELECT stuname,majorname
FROM stuinfo s
INNER JOIN major m ON s.`majorid`= m.`id`;
注意:创建好的视图在SQLyog中显示位置如下:
step2:对创建好的视图进行操作,从中筛选符合条件的数据
SELECT * FROM v1 WHERE stuname LIKE '张%';
2、修改视图(重新创建一个新视图):
语法:
CREATE OR REPLACE v1
AS
查询语句;
3、删除视图:
DROP VIEW myv1,myv2;
注意:可同时删除多个视图。
4、查看视图:
DESC v1;
SHOW CREATE VIEW v1;
5、更新视图中的数据:
#1.插入
INSERT INTO myv1 VALUES('张飞','zf@qq.com');
#2.修改
UPDATE myv1 SET last_name = '张无忌' WHERE last_name='张飞';
#3.删除
DELETE FROM myv1 WHERE last_name = '张无忌';
注意:视图数据的修改与表的修改相似,只需将table替换为view即可,但具备以下性质的视图不可被修改:
①包含以下关键字:分组函数、distinct、group by、having、union或者union all
②常量视图
③Select中包含子查询
④join
⑤from一个不能更新的视图
⑥where子句的子查询引用了from子句中的表
三、变量
1、分类:
系统变量
全局变量(global)
会话变量(session)
自定义变量
用户变量
局部变量
2、系统变量
①全局变量(所有会话均有效,但数据库重启后消失):
#案例一:查看所有的全局变量
SHOW GLOBAL VARIABLES;
#案例二:查看部分全局变量
SHOW GLOBAL VARIABLES LIKE '%char%';
#案例三:查看指定全局变量
SELECT @@global.autocommit;
#案例四:修改某个全局变量
SET @@global.autocommit=0;
②会话变量(仅对本次会话有效)
注意:其查看、修改与全局变量相似,只需要将global替换为session
3、自定义变量
①用户变量(作用域同会话变量):
#声明并初始化
SET @变量名=值;
#赋值(更新变量的值) #方式很多,仅举其一
SET @变量名=值;
#使用(查看变量的值)
SELECT @变量名;
②局部变量(仅在begin end中使用):
#声明
DECLARE 变量名 类型; 或
DECLARE 变量名 类型 【DEFAULT 值】;
#赋值(更新变量的值)
SET 局部变量名=值;
#使用(查看变量的值)
SELECT 局部变量名;
案例:声明两个用户变量,求和并打印
SET @n=6,@m=3;
SET @sum=@n*@m;
SELECT @sum;
四、存储过程
1、含义:将一组合法的SQL语句封装在一起构成存储过,程类似函数但存在区别。
2、创建语法:
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一组合法的SQL语句)
END
存储过程创建后在SQLyog中位置:
注意:
①参数列表包含:参数模式,参数名,参数类型。
②参数模式:in(输入)、out(输出)、inout(即可输入也可输出)
③如果存储过程体仅仅只有一句话,begin end可省略。
④SQL语句结尾要添加分号,存储过程结尾也要使用结束符号,结束符号要使用delimiter自定义
delimiter $
案例1:创建一个作用为向admin中插入一条新记录的存储过程(不使用参数模式)
DELIMITER $
CREATE PROCEDURE ins()
BEGIN
INSERT INTO admin(username,PASSWORD)
VALUES('Cindy',666666);
END$
调用:
CALL ins()$
注意:调用的 时候以$结尾因为创建存储过程前将结束语句修改为了$。
案例2:创建存储过程实现根据女生名,查询对应的男神信息(使用参数模式IN)
CREATE PROCEDURE cre(IN girl_name VARCHAR(20))
BEGIN
SELECT bo.boyName
FROM boys bo
INNER JOIN beauty b ON bo.id=b.boyfriend_id
WHERE b.name=girl_name;
END$
查询:
CALL rel('关晓彤')$
运行结果:
‘
案例3:传入a和b两个值,最终a和b都翻倍并返回(参数中包含INOUT)
CREATE PROCEDURE my_6(INOUT a INT,INOUT b INT)
BEGIN
SET a=a*2;
SET b=b*2;
END$
查询:
SET @m=5,@n=6$
CALL my_6(@m,@n)$
SELECT @m,@n$
注意:由于参数a、b即作为参数,也作为返回值,所以要先定义变量便于查询其返回值。
3、删除存储过程:
DROP PROCEDURE 存储过程名;
4、查看存储过程:
SHOW CREATE PROCEDURE 存储过程名;
五、函数
1、与存储过程的区别:函数有且仅有一个返回值,存储过程无要求。
2、创建语法:
CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
BEGIN
函数体
END
注意:
①参数列表包含变量名和变量类型
②函数体中必须要包含return
③begin end的用法和存储过程相同
函数创建后再SQLyog中的位置:
3、调用语法:
SELECT 函数名(参数);
案例1:返回公司员工个数
#创建函数
DELIMITER $
CREATE FUNCTION counts() RETURNS INT
BEGIN
SET @num=0; #注意分号的使用
SELECT COUNT(*) INTO @num
FROM employees;
RETURN @num;
END$
#调用函数
SELECT counts();
注意:
①函数的创建语法与存储过程的创建语法不同,使用returns。
②MySQL8.0版本创建函数时报错,解决方法如下:点击访问
4、查看、删除语法与存储过程相似,将procedure修改为function即可。
六、流程控制结构
1、if结构(if函数)
if 条件1 then 语句1;
elseif 条件2 then 语句2;
....
else 语句n;
end if;
注意:if结构只能用在begin end中
2、循环结构:while、loop、repeat
①循环控制:
iterate类似于 continue,继续,结束本次循环,继续下一次
leave 类似于 break,跳出,结束当前所在的循环
②语法:
#1.while
【标签:】while 循环条件 do
循环体;
end while【 标签】;
#2.loop
【标签:】loop
循环体;
end loop 【标签】;
#3.repeat
【标签:】repeat
循环体;
until 结束循环的条件
end repeat 【标签】;
案例:批量插入,根据次数插入到admin表中多条记录
DROP PROCEDURE pro_while1$
CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i<=insertCount DO
INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'666');
SET i=i+1;
END WHILE;
END $
调用:
SELECT pro_while1(100)$
注意:因为没有返回值,所以使用存储过程实现。