一、定义
存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集合,它存储在数据库中,一次编译后永久有效。用户可以通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程类似于Java中的方法,需要先定义,使用时再调用。
二、特点
- 封装性:存储过程将复杂的SQL语句封装在一起,形成一个独立的执行单元,从而简化了应用程序的代码。
- 重用性:存储过程可以在不同的时间、由不同的用户或不同的应用程序调用,提高了代码的重用性。
- 安全性:数据库管理员可以向访问数据库中存储过程的应用程序授予适当的权限,而不是向基础数据库表提供任何权限,从而提高了数据的安全性。
- 性能优化:存储过程在服务器端运行,且执行速度快。当客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而可降低网络负载。此外,存储过程执行一次后,产生的二进制代码就驻留在缓冲区,在以后的调用中,只需要从缓冲区中执行二进制代码即可,从而提高了系统的效率和性能。
三、参数类型
在MySQL存储过程中,参数可以分为以下三种类型:
- IN参数:表示调用者向存储过程传入的数据。IN参数是存储过程的输入参数,在调用存储过程时传递给存储过程,存储过程内部可以使用IN参数的值,但不能对其进行修改。
- OUT参数:表示存储过程向调用者返回的数据。OUT参数是存储过程的输出参数,存储过程执行完后会将结果赋值给OUT参数。
- INOUT参数:既表示调用者向存储过程传入的数据,也表示存储过程向调用者返回的数据。
存储过程概念
存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,它存储在数据库中,可以由应用程序通过一个调用执行。存储过程可以接受输入参数,也可以返回输出参数或结果集。使用存储过程可以提高代码的重用性、安全性和性能。
存储过程的创建
在MySQL中,创建存储过程使用CREATE PROCEDURE
语句。语法如下:
sql
CREATE PROCEDURE procedure_name (IN parameter_name datatype, OUT parameter_name datatype, ...)
BEGIN
-- SQL语句
END;
procedure_name
:存储过程的名称。- IN:表示输入参数。
OUT
:表示输出参数。datatype
:参数的数据类型。BEGIN ... END
:存储过程体,包含要执行的SQL语句。
存储过程的修改
MySQL不支持直接修改存储过程的定义,如果需要修改,通常的做法是删除原有的存储过程,然后重新创建一个新的。
存储过程的删除
使用DROP PROCEDURE
语句可以删除存储过程。语法如下:
sql
DROP PROCEDURE IF EXISTS procedure_name;
IF EXISTS
:可选的,用于在存储过程存在时才删除,避免错误。
查看存储过程
要查看存储过程的定义或状态,可以使用SHOW PROCEDURE STATUS
或查询information_schema.ROUTINES
表。
sql
SHOW PROCEDURE STATUS WHERE Db = 'database_name' AND Name = 'procedure_name';
-- 或者
SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = 'database_name' AND ROUTINE_NAME = 'procedure_name';
!!! 注意:字符串里面的``不是双引号也不是''''是``在数字1旁边波浪线的小写
存储过程的流程控制语句
存储过程中可以使用各种流程控制语句,如条件判断(IF
、CASE
)、循环(LOOP
、WHILE
、REPEAT
)等。
IF
语句:用于条件判断.
sql
IF condition THEN
-- SQL语句
ELSEIF another_condition THEN
-- SQL语句
ELSE
-- SQL语句
END IF;
CASE
语句:类似于IF
,但更适合处理多个条件
sql
CASE
WHEN condition1 THEN
-- SQL语句
WHEN condition2 THEN
-- SQL语句
ELSE
-- SQL语句
END CASE;
循环语句:LOOP
、WHILE
、REPEAT
用于执行循环操作。
sql
-- LOOP
my_loop: LOOP
-- SQL语句
IF condition THEN
LEAVE my_loop;
END IF;
END LOOP my_loop;
-- WHILE
WHILE condition DO
-- SQL语句
END WHILE;
-- REPEAT
REPEAT
-- SQL语句
UNTIL condition
END REPEAT;
存储过程练习题目
创建一个存储过程,计算两个数的和并返回结果\
创建一个存储过程,根据员工ID返回员工的姓名和工资。--此题比较有难度,可以放弃
创建一个存储过程,根据部门ID返回该部门所有员工的平均工资
创建一个存储过程,使用循环插入10条记录到某个表中。
如果上面的看不太懂的话
sql
create DATABASE myschool2 charset=utf8mb4
-- if 判断
create PROCEDURE o_4(in nam varchar(55),out chengji int)
BEGIN
DECLARE aa int;
DECLARE bb int;
select studentNo into aa from student_学员表 where studentName=nam;
select sum(studentResult) into bb from result_成绩表 where studentNo=aa;
if bb>60 then
set chengji=2;
elseif bb>40 then
set=1;
else
set=0;
end if;
END
call o_4('张三',@chengji);
-- switch循环 --case
use text1
desc checkitem_检查项目表
create PROCEDURE o_6(in neike varchar(55),out youhui varchar(55))
BEGIN
DECLARE zo int;
select sum(c.checkItemCost) into zo from department_科室表 dep
join prescription_处方表 p on p.depID=dep.depID
join checkitem_检查项目表 c on p.checkitemID=c.checkItemID
where c.checkItemName=neike;
case
when zo>200 and zo<500 then set youhui='优惠20%';
else
set youhui='无优惠';
end case;
END
call o_6('内科',@youhui)
select @youhui
create PROCEDURE o_7(in num int)
BEGIN
while num>0 DO
insert into x(id,number)values (num,num);
set num=num-1;
end while;
END
call o_7(10)
use myschool2
create PROCEDURE o_8(in xue int)
BEGIN
DECLARE aa int;
select count(1) into aa from student_学员表;
while xue<aa DO
UPDATE student_学员表 set address='普宁市';
set xue=xue+1;
end while;
END
call o_8(1);
create PROCEDURE o_10(out num int)
BEGIN
declare i int default 0;
DECLARE s int default 0;
x:loop
set i=i+1;
if i>100 THEN
leave x;
end if;
set s=i+s;
end loop x;
set num=s;
END
CREATE PROCEDURE o_11 ( OUT aa INT ) BEGIN
DECLARE
sum INT DEFAULT 0;
DECLARE
i INT DEFAULT 0;
x :
LOOP
IF
i < 100 THEN
SET i = i + 1;
IF
i % 2 = 0 THEN
SET sum = sum + i;
END IF;
ELSE LEAVE x;
END IF;
END LOOP x;
SET aa = sum;
END
call o_11(@aa);
select @aa;
-- 练习
use myschool2
create PROCEDURE oo_1()
BEGIN
select * from grade_年级表;
END
create PROCEDURE oo_2(in hao int )
BEGIN
select * from result_成绩表 r
join student_学员表 s on s.studentNo=r.studentNo
where s.studentNo=hao;
END
create PROCEDURE oo_3(in na varchar(55))
BEGIN
select s.loginPwd,s.studentName,s.sex,g.gradeName,s.studentNo,s.phone,s.address,s.bornDate,s.email,s.identityCard from student_学员表 s
join grade_年级表 g on s.gradeId=g.gradeId
where s.studentName=na;
END
create PROCEDURE oo_4(in aa int,in bb int,in cc datetime,in dd int)
BEGIN
insert into result_成绩表 VALUES(aa,bb,cc,dd);
END
create PROCEDURE oo_5(in hao int,in mim int)
BEGIN
UPDATE student_学员表 set loginPwd=mim where studentNo=hao;
END
create PROCEDURE oo_10(in g varchar(10),in gid int,in birthDay varchar(50))
BEGIN
if birthDay!=null then
select * from student_学员表 where sex=g and gradeId=gid and bornDate=birthDay;
ELSE
select * from student_学员表 where sex=g and gradeId=gid;
end if;
END
desc student_学员表
desc result_成绩表
desc grade_年级表
create PROCEDURE oo_6(in bianhao int)
BEGIN
select avg(r.studentResult) from result_成绩表 r
join subject_课程表 s on s.subjectNo=r.subjectNo
where s.subjectNo=bianhao
GROUP BY r.studentResult;
END
create PROCEDURE oo_7()
BEGIN
select g.gradeName,count(1) from student_学员表 s
join grade_年级表 g on s.gradeId=g.gradeId
GROUP BY g.gradeName;
END
create PROCEDURE getvaluer(out num int)
BEGIN
DECLARE j,s int DEFAULT 0;
x:REPEAT
set i=i+1;
set s=s+i;
UNTIL i>100 END REPEAT x;
set num=s;
END
create PROCEDURE orde_1(in da varchar(55))
BEGIN
select MONTH(createTime),count(1) from orde表 where MONTH(createTime)=da
GROUP BY orderId;
END
-- 删除存储过程
drop PROCEDURE orde_1
drop PROCEDURE if EXISTS orde_1
-- 查看存储过程 信息
show PROCEDURE STATUS like 'orde_1';
-- 修改存储过程权限
alter PROCEDURE orde_1 SQL security invoker;
-- DEFINER:必须定义者(创建存储过程的那个用户)有运行权限否则无法执行和当前登录的用户权限没有关系
-- invoker :执行者(当前登录的用户)有权限即可定义者(创建存储过程的那个用户)无关
以上是我做题的一些例子,可以自行观看