MySQL高级第三章——视图和函数

学习目标:

  1. 了解视图的作用
  2. 熟练掌握视图的创建、更新、删除操作
  3. 熟练掌握自定义函数的创建和调用
  4. 理解函数和过程的区别

学习内容:

1、 视图
2、 函数


学习时间:

2021/2/12


视图

视图简介:
1) 为什么要使用视图?
a) 从三大范式当中,我们知道一张表只存一种实体的数据,但现实业务往是,需要多个表的数据关联呈现的,并且某些固定的列会被频繁的访问,视图可以避免频繁的编写这些关联查询语句;
b) 某些人可能只允许表中的部分列,不能将整个表的列或数据行暴露出来,我们可以为这些特定的人创建一个视图,把权限给到这些人,起到对基表中的其他列和数据行进行安全保护;视图中存储了可以返回结果集的 sql 查询语句,当用在 from 子句时,内部的 sql 查询语句就会被执行。


2) 什么是视图?

MySQL 视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。
但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在
引用视图时动态生成。
视图的优点:

  1. 简单化,数据所见即所得;
  2. 安全性,用户只能查询或修改他们所能见到得到的数据;
  3. 逻辑独立性,可以屏蔽真实表结构变化带来的影响。视图的缺点:
  4. 性能相对较差,从视图查询数据可能会很慢,特别是如果视图是基于其他视图创建的;
  5. 修改不方便,特别是复杂的聚合视图基本无法修改。

MySQL 中视图的使用

1、基于单表创建视图

学生表创建语句:

DROP TABLE IF EXISTS `studentinfo`;
CREATE TABLE `studentinfo`  (
  `StudentID` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '学号',
  `StudentName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '姓名',
  `Gender` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '性别 默认值为男',
  `Age` int(11) NULL DEFAULT 0 COMMENT '年龄',
  `Birthday` datetime(0) NOT NULL COMMENT '出生日期',
  `StudentNO` varchar(18) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '学员身份证号码唯一约束',
  `ClassID` int(11) NOT NULL DEFAULT 0 COMMENT '班级编号',
  `BeginTime` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '入学时间非空',
  `Phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '电话非空',
  `Province` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '河南' COMMENT '户籍所在省默认值河南',
  `City` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '郑州' COMMENT '户籍所在市',
  `Email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '电子邮件非空',
  `DormitoryNo` varchar(5) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '宿舍号',
  PRIMARY KEY (`StudentID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of studentinfo
-- ----------------------------
INSERT INTO `studentinfo` VALUES ('2011001002', '亡灵战神', '男', 22, '1991-02-21 00:00:00', '410702199102210213', 1, '2011-5-6', '15125741526', '河南', '周口', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011001003', '战争女神', '女', 23, '1990-06-21 00:00:00', '410303199006210215', 1, '2011-5-6', '15890172541', '河南', '洛阳', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011001004', '黑暗之女', '女', 23, '1990-02-11 00:00:00', '412701199002110618', 1, '2011-5-6', '18637165241', '河南', '周口', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011001006', '狂战士', '男', 20, '1990-10-14 00:00:00', '410102199010140317', 1, '2011-5-6', '15569852141', '河南', '郑州', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011001008', '正义巨像', '男', 22, '1991-06-21 00:00:00', '410103199106210613', 1, '2011-5-6', '15142153256', '河南', '郑州', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011001009', '卡牌大师', '男', 22, '1991-11-15 00:00:00', '410702199111150517', 1, '2011-5-6', '15125741529', '河南', '洛阳', '王[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011001010', '德邦总管', '男', 21, '1992-05-06 00:00:00', '410306199205060719', 1, '2011-5-6', '15125471535', '河南', '洛阳', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011001011', '无畏站车', '男', 22, '1991-08-19 00:00:00', '412702199108090103', 1, '2011-5-6', '15125471539', '河南', '周口', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011003001', '诡术妖姬', '女', 22, '1991-11-07 00:00:00', '410106199111070412', 3, '2011-5-6', '18854215874', '河南', '郑州', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011003002', '猩红收割者 ', '女', 18, '1989-06-04 00:00:00', '411303198906040102', 3, '2011-5-6', '17878452365', '河南', '南阳', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011003003', '末日使者', '男', 23, '1990-05-29 00:00:00', '410522199005290213', 3, '2011-5-6', '18878452361', '河南', '安阳', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011003004', '正义天使', '女', 23, '1990-09-16 00:00:00', '410104199009160416', 3, '2011-5-6', '16878452397', '河南', '郑州', '[email protected]', '4102');
INSERT INTO `studentinfo` VALUES ('2011003007', '无极剑圣', '女', 21, '1992-01-07 00:00:00', '410102199201070317', 3, '2011-5-6', '13852417412', '河南', '郑州', '[email protected]', '4102');

  1. 创建视图,显示学生姓名、性别、年龄和所在班级编号
create view v_v1 -- view视图的关键词
as -- as后面跟上sql
select 
studentName,Gender,Age,ClassID 
from studentinfo;-- 视图就是有查询组成的
-- 查询视图
select * from v_v1;

运行结果:
在这里插入图片描述

  1. 使用别名的视图,创建视图,显示学生姓名、性别、年龄和所在班级编号,并以中文表头显示
create view v_v2(姓名,性别,年龄,班级) -- view视图的关键词
as -- as后面跟上sql
select 
studentName,Gender,Age,ClassID 
from studentinfo;
-- 查询视图
select * from v_v2;

在这里插入图片描述


基于多表创建视图

班级表(classinfo):

DROP TABLE IF EXISTS `classinfo`;
CREATE TABLE `classinfo`  (
  `cid` int(11) NOT NULL,
  `canme` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of classinfo
-- ----------------------------
INSERT INTO `classinfo` VALUES (1, '网开一班');
INSERT INTO `classinfo` VALUES (2, '网开二班');
INSERT INTO `classinfo` VALUES (3, '网开三班');



创建视图,显示学生姓名、性别、年龄和所在班级名称


create view v_v3
as
SELECT
	studentinfo.StudentName,
	studentinfo.Gender,
	studentinfo.Age,
	classinfo.canme
FROM
	classinfo
INNER JOIN studentinfo ON classinfo.cid = studentinfo.ClassID
;

select * from v_v3;-- 视图的数据来源于(基表)

运行结果:
在这里插入图片描述


使用视图更新数据

select * from v_v1;
-- 把v_v1所有的年龄字段都加一
update v_v1 set age=age+1;-- 修改视图、改的是(基表)

修改前:
在这里插入图片描述
修改后:
在这里插入图片描述
注意:
在 MySQL 中,视图不仅是可查询的,而且是可更新的。这意味着您可以使用 INSERT 或 UPDATE 语句通过可更新视图插入或更新基表的行。另外,您可以使用 DELETE 语句通过视图删除底层表的行。但是,要创建可更新视图,定义视图的 SELECT 语句不能包含以下任何元素:

  1. 聚合函数;
  2. distinct 子句;
  3. group by 子句;
  4. having 子句;
  5. union 和 union all 子句;
  6. 外连接
    不建议使用基于多表创建的视图进行更新操作。

#### WITH CHECK OPTION 子句 有时候,创建一个视图来显示表的部分数据。然而,简单视图是可更新的,因此可以更新通过视图不可见的数据。此更新使视图不一致。为了确保视图的一致性,在创建或修改视图时使用 WITH CHECK OPTION 子句。
create view v_4
as
select * from subject where CreditHour>24;
-- 通过视图查询
select * from v_4;
-- 通过视图添加新课程
insert into v_4 values(null,'java基础 wk22',20,1,1);
-- 查询课程表
select * from v_4;

select * from subject;

视图运行结果:
在这里插入图片描述
查询表结构:
在这里插入图片描述
在这里我们的视图并限制成功了没有添加上数据,但是我们的表中却添加了数据,表示我们的数据没有同步,这是我们就需要WITH CHECK OPTION 子句了

-- 修改视图
alter view v_v4
as
select * from subject where CreditHour>24 with check option;
-- 通过视图添加新课程
insert into v_v4 values(null,'layui',20,1,1);

在这里插入图片描述
在这里我们可以看到执行并不成功,表示我们的限制成功了


函数

函数简介:
MySQL 中的函数和 JavaScript 中的函数作用类似,就是执行特定任务的代码块。 其实,大家已经有过在 MySQL 中使用函数的经验了,比如我们获得系统时间,可以用 now()函数,求平均值 可以用 avg()函数等等。这些系统定义好的函数我们称为系统函数,可以直接拿来使用,但有些时候我们需要完成 特定功能,就需要自己定义函数。用户自己定义的函数,称为自定义函数。

MySQL 中函数的使用

创建函数的语法

create function 函数名([参数列表]) returns 数据类型
begin
sql 语句;
return;
end;

练习:

1、创建一个函数,返回学号为“2011001002”的学生姓名

reate function ff1() returns varchar(20)-- returns 返回值类型
begin-- 相当于花括号{}
	declare n varchar(20);-- 定义一个变量
	select 
	studentName into n-- into 赋值 (n)
	from studentinfo 
	where studentID='2011001002';
	return n;-- 返回值
end;
-- 调用函数
select ff1();

运行结果:
在这里插入图片描述
2、创建一个带参数的函数,输入学号,返回学生姓名

create function ff2(sid varchar(20)) returns varchar(20)
begin
	declare n varchar(20);-- 定义一个变量
	select 
	studentName into n-- into 赋值 (n)
	from studentinfo 
	where studentID=sid;
	return n;-- 返回值
end;
-- 调用函数
select ff2('2011001002');

运行结果:
在这里插入图片描述


#### 注意: 1. 函数名后面有一对小括号,括号内可以填写或不填参数,但括号不能省略; 2. 小括号后必须跟 returns,returns 后跟返回值类型,类型必须是 MySQL 中的类型; 3. 函数主体放在 begin..end 内,end 前要 return 与前面 returns 后跟的类型相同的值; 4. select 查询结果也可以用来给变量赋值,但是需要用 into 关键词
## 总结:

函数与过程的区别:

  1. 返回值不同:函数必须有返回值,且仅返回一个结果值;过程可以没有返回值,但是能返回结果集;
  2. 调用时的不同:函数使用 select 进行调用;过程使用 call 进行调用;
  3. 参数的不同:函数的参数都是 in 参数;过程可以传递 in\out\inout 参数。

视图的作用:

视图中存储了可以返回结果集的 sql 查询语句,当用在 from 子句时,内部的 sql 查询语句就会被执行

更新视图有的限制

**定义视图的 SELECT 语句不能包含以下任何元素: **

1 、聚合函数;
2 、distinct 子句;
3 、group by 子句;
4、 having 子句;
5、union 和 union all 子句;
6、 外连接

注意:不建议使用基于多表创建的视图进行更新操作。

函数的注意事项:

  1. 函数名后面有一对小括号,括号内可以填写或不填参数,但括号不能省略;

  2. 小括号后必须跟 returns,returns 后跟返回值类型,类型必须是 MySQL 中的类型;

  3. 函数主体放在 begin…end 内,end 前要 return 与前面 returns 后跟的类型相同的值;

  4. select 查询结果也可以用来给变量赋值,但是需要用 into 关键词。

函数与存储过程的不同

  1. 返回值不同:函数必须有返回值,且仅返回一个结果值;过程可以没有返回值,但是能返回结果集;

  2. 调用时的不同:函数使用 select 进行调用;过程使用 call 进行调用;

  3. 参数的不同:函数的参数都是 in 参数;过程可以传递 in\out\inout 参数

猜你喜欢

转载自blog.csdn.net/zhou_yuandong/article/details/114699986