视图、存储过程、触发器

视图

– 还是以学生管理系统为例,假定MySQL任课老师需要查看学生考试成绩,
– 我们可以采用视图为任课教师提供查看学生考试成绩的视图,数据包括姓名,
– 学号,成绩,课程名称。
create view 视图名
CREATE view vw_score
AS
– select 语句
select name,student.stuid,socre,subname from student,score,subject
where student.stuid=score.stuid and score.subid=subject.subid
and subname=‘MySQL’;

怎么调用一个视图
select * from vw_score
where name=‘张三’;

– 视图就是一个由查询结果组成的一个虚拟表
删除一个视图
drop view vw_score;

desc vw_score;

小结:
– 原表的数据发生改变,那么视图的查询结果会随之改变。
– 视图的数据修改之后,原表的数据也会改变。
– 视图是表的查询结果,如果表的数据发生增删改,name视图数据也会发生改变;反之相同。
– 但是一般不会对视图进行增删改,例如视图只显示了原表的几个字段,如果添加的话,原表
– 可能有一些非空字段,这时用视图做添加操作,肯定会有问题。

存储过程
优点:
执行速度更快
允许模块化程序设计
提高系统安全性
减少网络流通量

存储过程参数:
存储过程的参数分三种:
输入参数(in):
向存储过程传入值
输出参数(out):
调用存储过程后,传出执行结果
输入输出参数(inout):
把数据传递给存储过程和将存储过程的返回值传递给外部使用者
Inout代表即是输入参数,又是输出参数,表示该参数的值即可以由
调用程序指定,又可以将inout参数的计算结果返回给调用程序。

存储过程变量:
常用的存储过程变量分为两种:用户变量和局部变量。
(1)用户变量:用户定义的变量就叫用户变量,以"@“开始,形式为”@变量名"。用户变量跟mysql客户端是绑定的,设置的变量,只对当前用户使用的客户端生效
(2)局部变量:作用范围在begin到end语句块之间。在该语句块里设置的变量。declare语句专门用于定义局部变量。
DECLARE 变量名 [,…] 变量类型[DEFAULT value]

局部变量和用户变量的区别
局部变量与用户变量的区分在于两点:
用户变量是以"@"开头的。局部变量没有这个符号。
定义变量不同,局部变量使用declare语句定义 。
作用范围。局部变量只在begin-end语句块之间有效。在begin-end语句块运行完之后,局部变量就消失了。

创建存储过程:
CREATE PROCEDURE 存储过程名 (参数)
– BEGIN END 相当于java方法的大括号
– 查询MySQL科目的最高分
create PROCEDURE usp_maxMysqlScore()
BEGIN
– sql语句
select subname,MAX(socre) from score,subject
where score.subid=subject.subid
and subname=‘MySQL’;
END

调用存储过程
call usp_maxMysqlScore();

– 输入参数 in :(由用户调用存储过程时输入)
– 查询某一科考试没有及格的学生姓名,成绩,科目。
– 输入参数:科目,成绩及格线
create PROCEDURE usp_studentScore(in sc int,in suname VARCHAR(20))
BEGIN
– 查询某一科考试没有及格的学生姓名,成绩,科目。
select name,socre,subname from student,score,subject
where student.stuid=score.stuid and score.subid=subject.subid
and subname=suname and socre>sc;
END

call usp_studentScore(60,‘MySQL’);

删除存储过程
DROP PROCEDURE usp_maxScore;

– out :输出参数把执行结果返回给调用者
– 创建查找指定科目的最高分 输入参数科目,输出参数分数
create PROCEDURE usp_maxScore(in suname varchar(20),out maxsc int)
BEGIN
– 查询指定科目的最高分
select MAX(socre) from subject,score
where subject.subid=score.subid
and subname=suname into maxsc; – 把查询的结果赋值给maxsc
END
– 执行存储过程,定义一个成员变量 @maxsc 语法:变量名
call usp_maxScore(‘MySQL’,@maxsc);
– 查询最高分
select @maxsc;

– 查询某科考试没有及格的学生姓名,并获得参加考试的人数
– 和未及格的人数。
– 输入参数:科目名;输出参数:参加考试人数 未及格人数
create PROCEDURE usp_getCount(in suname varchar(20),out testCount int,out noTestCount int)
BEGIN
– 查询某科考试没有及格的学生姓名
select name,socre from student INNER JOIN score
on student.stuid=score.stuid
INNER JOIN subject on score.subid=subject.subid
where subname=suname and socre<60;
– 并获得参加考试的人数
select COUNT() from subject,score
where subject.subid=score.subid
and subname=suname into testCount;
– 未及格人数
select COUNT(
) from score,subject
where score.subid=subject.subid
and subname=suname and socre<60 into noTestCount;
– 输入参数:科目名;输出参数:参加考试人数 未及格人数
END
drop PROCEDURE usp_getCount;

call usp_getCount(‘MySQL’,@testCount,@noTestCount);
select @testCount,@noTestCount;
– 传一个年龄,自动让年龄增长10岁
create PROCEDURE usp_age(inout age int)
BEGIN
set age=age+10;
END
– 定义一个变量
set @age=10;
call usp_age(@age);

select @age;

流程控制
– 一女生向你表白,如果她长得貌美如花,你说“咱俩结婚吧”,
– 如果长得“还可以”,你说“考虑一下”,否则说“NO”。
create PROCEDURE getGrad(in text varchar(20))
BEGIN
DECLARE a varchar(20);
– 判断输入内容
if text=‘貌美如花’ then
set a=‘咱们结婚吧’;
elseif text=‘还可以’ THEN
set a=‘考虑一下’;
else
set a=‘NO’;
end IF;
select a;
END
drop PROCEDURE getGrad;

call getGrad(‘貌美如花’);

存储过程和存储函数的不同:
存储函数不能拥有输出参数,因为存储函数自身就是输出参数,只能有
一个返回值;而存储过程可以拥有多个输出参数。
可以直接对存储函数进行调用,而不需要使用call语句;而对存储过程的
调用,需要使用call语句。
存储函数中必须包含一条return语句,而这条特殊的sql语句不允许包含
于存储过程中。
存储过程中的语句功能更强大,存储过程可以实现很复杂的业务逻辑,
而函数有很多限制,如不能在函数中使用insert,update,delete,create等
语句;存储函数只完成查询的工作,可接受输入参数并返回一个结果,也
就是函数实现的功能针对性比较强。
存储过程可以调用存储函数。但函数不能调用存储过程。

触发器
触发器是一种特殊的存储过程,当在某个数据表中插入、修改、或删除记录时,触发器会自动被触发执行。

创建触发器的语法
create trigger 触发器名称
after/before (触发时间)
insert/update/delete (监视事件)
on 表名 (监视地址)
for each row --定死的
begin
sql1;

sqlN;
End

删除触发器:
drop trigger 触发器名称
查看触发器定义:
SHOW CREATE TRIGGER 搜索触发器名称
查看触发器:
SELECT * FROM information_schema.triggers

例题:
– 数据库productorder。
– (1)创建触发器recruit_insert当有一批新的产品入库时,供应商库存数量自动更新
create trigger recruit_insert
AFTER
INSERT
on recruit
for each row
BEGIN
update product set pcount=pcount+new.rcount where pid=new.pid;
END

– (2)创建触发器recruit_delete当入库需求取消时,供应商库存数量自动更新
create TRIGGER recruit_delete
after
DELETE
ON recruit
for EACH ROW
BEGIN
update product set pcount=pcount-old.rcount where pid=old.pid;
END
DELETE from recruit where rid=9;

– (3)创建触发器recruit_update当库存不要那么多产品时(修改入库订单数量),
– 供应商库存数量自动更新
create TRIGGER recruit_update
AFTER
UPDATE
on recruit
FOR EACH ROW
BEGIN
update product set pcount=pcount-old.rcount+new.rcount where pid=new.pid;
END

after 和 before 的区别:
after 是先完成数据的增删改,再触发,触发的语句晚于监视的增删改操作,无法影响前面的增删改动作;也就是说先插入订单记录,再更新商品的数量;
before 是先完成触发,再增删改,触发的语句先于监视的增删改,我们就有机会判断,修改即将发生的操作;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值