三.存储过程
存储过程和函数类似,可以理解成为数据库里一种特殊的函数对象,其也可以用于自定义功能,并且功能更加强大,所以MySQL数据库中一般使用存储过程比使用自定义函数方便。
存储过程关键字:procedure
1.创建无参存储过程
创建无参存储过程的基本格式:
# 存储过程的创建和使用 delimiter <自定义结束符> create procedure 存储过程名() begin SQL语句1; SQL语句2; ······ end <自定义结束符> delimiter;
例如:
delimiter // create procedure select_stu() begin -- 复合语句开始,相当于c++语言中的大括号; select s_id from student where s_id>3; -- 存储过程支持SQL语句; select s_name from student where s_id>3; select s_cid from student where s_id>3; end// delimiter ; call select_stu(); -- 执行存储过程与视图相似;
2.存储过程的调用
存储过程的调用基本格式:call 存储过程(参数列表);
3.查看已创建的指定存储过程的相关信息
基本格式:show create procedure 存储过程名;
4.查看已创建的所有存储过程的相关信息
基本格式:show procedure ststus;
5.存储过程的删除
基本格式:drop procedure <存储过程名>;
6.修改存储过程
MySQL还不支持修改存储过程的代码,只能先将原来的存储过程删除后,在重新创建;
7.带参存储过程
①.创建带参存储过程的基本格式;
delimiter 自定义结束符 create procedure 存储过程名(参数类型 参数名1 数据类型,参数类型 参数名2 数据类型,参数类型 参数名3 数据类型·······) begin SQL语句; end 自定义结束符 delimiter ;
②.参数类型
MySQL数据库中存储过程的参数有3种类型,分别为:in,out,inout.
1.-- in;传入型参数,用于将参数值传递进入存储过程中; 2.-- out传出型数据,用于将存储过程中的值传递出来; 3.-- inout传入传出型数据,既可以用于参数值传递进存储过程,又可以将值从存储过程传出;
③.带参存储过程的调用;
call 存储过程(参数1,参数2,参数3·····)
④.带参存储过程的演示示例
代码:
#带参存储过程的演示示例 -- 运用存储过程完成查询语句; delimiter // create procedure get_class_name(in cid int) begin select db_2.class.c_id from class where c_id=cid; end// delimiter ; -- 带参存储过程的调用; call get_class_name(100); call get_class_name(103);
示例2:代码演示:
#运用带参存储过程进行数据的插入; delimiter // create procedure insert_student(in sid int, sname varchar(20),scid int,ssex varchar(4),sage int) -- in可以省略,out,inout不可以省略; begin insert into student values(sid,sname,scid,ssex,sage); end// delimiter ; -- 带参调用 call insert_student(116,"可可",2,'女',18);
#运用带参存储过程进行修改操作; delimiter // create procedure update_student(in sid int,sname varchar(20)) begin update student set s_name=sname where s_id=sid; end// delimiter ; -- 带参存储过程的调用; call update_student(100,'李娟'); select * from student;-- 操作完成,查看;
源代码呈现
use db_2; -- 使用数据库; select now(); -- 获取现在的时间函数 select date('2000-1-1 6:30:30'); -- 获取指定时间日期数据类型中的日期函数; select time("2020-7-31 14:36:31"); -- 获取指定日期时间数据类型中的时间函数; select date_format(now(),"%Y-%m-%d %H:%i:%s"); -- 将日期转换为字符串类型; -- ①.小写字母转大写:`upper` select upper('abc'); -- ②.求字符串子串:`substring` select substring('123abc@#$XYZ',3,8); -- 从第三个开始,截取8个长度的子串; -- ③.四舍五入函数:`round()` select round(123.456); -- 只保留整数 select round(123.456,1);-- 保留1位小数 -- ④.求次方函数:`power,pow` select power(4,5); -- 举一反三: select power(9,1/2); -- 求9的开根号; -- ⑤.获取当前数据库名:`database()` select database(); -- ⑥.获取字符串的长度:`length()` select length("123,456,7,dfghr"); -- ⑦.字符串连接函数,连接多个字符串:`concat()` select concat("1,34",'123','4frghy'); #自定义函数; /* create function power2( returns 返回值类型 begin 函数体语句 return (函数返回结果) end; ); */ -- 创建一个求和函数 create function sum1(x int,y int) returns int return x+y; -- 单条语句可以不使用begin,end; set global log_bin_trust_function_creators=true; -- 关闭生命周期安全检查; select sum1(2,3); -- 结果查询; #自定义结束符delimiter在函数中的使用; delimiter // -- 定义分隔符为//,此后的结束符都是//; create function sum1(x int,y int) returns int begin return x+y end // delimiter ; # 存储过程的创建和使用 ```sql /* delimiter <自定义结束符> create procedure 存储过程名() begin SQL语句1; SQL语句2; ······`· end <自定义结束符> delimiter; */ delimiter // create procedure select_stu() begin -- 复合语句开始,相当于c++语言中的大括号; select s_id from student where s_id>3; -- 存储过程支持SQL语句; select s_name from student where s_id>3; select s_cid from student where s_id>3; end// delimiter ; call select_stu(); -- 执行存储过程与视图相似; #查看指定存储过程 show create procedure select_stu; #查看存储过程; show procedure status; #带参存储过程的演示示例 delimiter // create procedure get_class_name(in cid int) begin select db_2.class.c_id from class where c_id=cid; end// delimiter ; -- 带参存储过程的调用; call get_class_name(100); call get_class_name(103); #运用带参存储过程进行数据的插入; delimiter // create procedure insert_student(in sid int, sname varchar(20),scid int,ssex varchar(4),sage int) -- in可以省略,out,inout不可以省略; begin insert into student values(sid,sname,scid,ssex,sage); end// delimiter ; -- 带参调用 call insert_student(116,"可可",2,'女',18); #运用带参存储过程进行修改操作; delimiter // create procedure update_student(in sid int,sname varchar(20)) begin update student set s_name=sname where s_id=sid; end// delimiter ; -- 带参存储过程的调用; call update_student(100,'李娟'); select * from student;-- 操作完成,查看;
上面是我们本节讲解的代码示例,可以直接去运行,方便大家查看,我直接将代码发出来了;涉及到一些表的建立,只有使用了我给的表,上面的代码才能使用,代码在附件;
附件(数据表代码) create database if not exists db_2; use db_2; #创建学生,班级,教师的数据表; -- 教师表 create table teacher( t_id int primary key auto_increment, t_name varchar(20) not null, t_sex varchar(4) check(t_sex='男'||t_sex='女'), t_age int check(t_age>=20 and t_age<=60) )auto_increment=100; desc teacher; show columns from teacher; insert into teacher(t_name,t_sex,t_age) values('小威','男','28'),('靓靓','女','20'),('丸子','女','23'), ('易木','男','27'),('龙卷风','男','30'),('桃子','女','21'),('robert','男','40'),('可达','男','28'), ('荔枝','女','22'),('教主','男','29'); -- 班级表 create table class( c_id int primary key auto_increment, c_name varchar(30) not null, c_tid int, -- 班级的认可老师/班主任老师; c_stunum int default 0,-- 班级人数 constraint for_CT foreign key(c_tid) references teacher(t_id)on update cascade on delete set null )auto_increment=100; insert into class(c_name,c_tid)values ('c语言',101),("c++",103),("数据结构",106),("win32",NULL),("游戏开发",107), ("QT",NULL),("Linux服务器",NULL); -- 学生表 create table student( s_id int primary key auto_increment, s_name varchar(20) not null, -- 非空约束; s_cid int, -- 学生属于的班级 s_sex varchar(4) check(s_sex='男' or s_sex='女'), s_age int check(s_age>=18 and s_age<=40), constraint for_SC foreign key(s_cid) # 设置为外键; references class(c_id) on update cascade on delete set null )auto_increment=100; insert into student(s_name,s_cid,s_sex,s_age) values ('陈小皮',100,'男',20),('吉利服',103,'男',20), ('张益达',100,'男',20),('萌萌',103,'女',20),('晓东',101,'男',20),('小蔡',null,'男',21), ('小玉',102,'女',21),('阿雪',103,'女',21),('如花',null,'女',25),('似玉',null,'女',24),('小桂子',null,'男',22), ('小强子',101,'男',23),('小吴',102,'男',24),('小花',100,'女',23),('小丸子',null,'女',20),('小红',101,'女',21);
总结
本节我们学习了函数和存储过程,函数我们只需要掌握常用的库函数就可以,自定义函数使用较少,不需要掌握,存储过程使用较多,由于它不被SQL语句限制,故掌握好存储过程更有利后面的使用。