本篇文章给大家分享学习mysql存储过程时的笔记,其咋哄详细介绍了mysql储存过程的相关知识,希望对大家有帮助。
|
本篇文章给大家分享学习mysql存储过程时的笔记,其咋哄详细介绍了mysql储存过程的相关知识,希望对大家有帮助。
一、定义存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。 二、存储过程的特点 1、能完成较复杂的判断和运算 三、创建一个简单的存储过程1、创建存储过程的简单语法 create procedure 名称() begin ......... end 2、创建一个简单的存储过程 create procedure testa()
begin
select * from users;
select * from orders;
end;3、调用存储过程 call testa(); 运行结果如图(1)和图(2):
图(1)
图(2) 四、存储过程的变量1、先通过一个简单的例子来学习变量的声明和赋值 create procedure test2() begin -- 使用 declare语句声明一个变量 declare username varchar(32) default ''; -- 使用set语句给变量赋值 set username='xiaoxiao'; -- 将users表中id=1的名称赋值给username select name into username from users where id=1; -- 返回变量 select username; end; 2、概括 (2)、变量具有数据类型和长度,与mysql的SQL数据类型保持一致,因此甚至还能制定默认值、字符集和排序规则等; 五、变量的作用域 1、变量作用域说明: 需求: 创建一个存储过程,用来统计表users、orders表中行数数量和orders表中的最大金额和最小金额 create procedure test3()
begin
begin
declare userscount int default 0; -- 用户表中的数量
declare ordercount int default 0; -- 订单表中的数量
select count(*) into userscount from users;
select count(*) into ordercount from orders;
select userscount,ordercount; -- 返回用户表中的数量、订单表中的数量
end;
begin
declare maxmoney int default 0; -- 最大金额
declare minmoney int default 0; -- 最小金额
select max(money) into maxmoney from orders;
select min(money) into minmoney from orders;
select maxmoney,minmoney; -- 返回最金额、最小金额
end;
end;调用以上存储过程,结果如图(3)和图(4):
(3) 3、我将过程test(3)改为如下: create procedure test3() begin begin declare userscount int default 0; -- 用户表中的数量 declare ordercount int default 0; -- 订单表中的数量 select count(*) into userscount from users; select count(*) into ordercount from orders; select userscount,ordercount; -- 返回用户表中的数量、订单表中的数量 end; begin declare maxmoney int default 0; -- 最大金额 declare minmoney int default 0; -- 最小金额 select max(money) into maxmoney from orders; select min(money) into minmoney from orders; select userscount,ordercount,maxmoney,minmoney; -- 返回最金额、最小金额 end; end; 再次调用call test3(); 会报错如图(5):
图(5) 4、将userscount,ordercount改为全局变量,再次验证 create procedure test3() begin declare userscount int default 0; -- 用户表中的数量 declare ordercount int default 0; -- 订单表中的数量 begin select count(*) into userscount from users; select count(*) into ordercount from orders; select userscount,ordercount; -- 返回用户表中的数量、订单表中的数量 end; begin declare maxmoney int default 0; -- 最大金额 declare minmoney int default 0; -- 最小金额 select max(money) into maxmoney from orders; select min(money) into minmoney from orders; select userscount,ordercount,maxmoney,minmoney; -- 返回最金额、最小金额 end; end; 再次调用call test3(); 会报错如图(6)和图(7):
图(6)
图(7) 因此,存储过程中变量的作用域,作用范围在begin和end块之间,end结束变量的作用范围即结束 六、存储过程参数1、基本语法 create procedure 名称([IN|OUT|INOUT] 参数名 参数数据类型 ) begin ......... end 存储过程的参数类型有:IN,OUT,INOUT,下面分别介绍这个三种类型: 说明: (1)、传入参数:类型为in,表示该参数的值必须在调用存储过程事指定,如果不显示指定为in,那么默认就是in类型。 (2)、IN类型参数一般只用于传入,在调用过程中一般不作为修改和返回 (3)、如果调用存储过程中需要修改和返回值,可以使用OUT类型参数 通过一个实例来演示: 需求:编写存储过程,传入id,根据id返回name create procedure test4(userId int)
begin
declare username varchar(32) default '';
declare ordercount int default 0;
select name into username from users where id=userId;
select username;
end;运行如图(8)
图(8) 需求:调用存储过程时,传入userId返回该用户的name create procedure test5(in userId int,out username varchar(32)) begin select name into username from users where id=userId; end; 调用及运行结果如图(9):
图(9) 1、传出参数:在调用存储过程中,可以改变其值,并可返回; 2、out是传出参数,不能用于传入参数值; 3、调用存储过程时,out参数也需要指定,但必须是变量,不能是常量; 4、如果既需要传入,同时又需要传出,则可以使用INOUT类型参数 (3).存储过程的可变参数INOUT create procedure test6(inout userId int,inout username varchar(32))
begin
set userId=2;
set username='';
select id,name into userId,username from users where id=userId;
end;调用及运行结果如图(10)
图(10) 七、存储过程条件语句1、基本结构 (1)、条件语句基本结构: if() then...else...end if; (2)、多条件判断语句: if() then... elseif() then... else ... end if; 2、实例 create procedure test7(in userId int)
begin
declare username varchar(32) default '';
if(userId%2=0)
then
select name into username from users where id=userId;
select username;
else
select userId;
end if;
end;调用及运行结果如图(11)和图(12):
图(11)
图(12) 2、存储过程的多条件语句应用示例 需求:根据用户传入的uid参数判断 (1)、如果用户状态status为1,则给用户score加10分; (2)、 如果用户状态status为2,则给用户score加20分; (3)、 其他情况加30分 create procedure test8(in userid int)
begin
declare my_status int default 0;
select status into my_status from users where id=userid;
if(my_status=1)
then
update users set score=score+10 where id=userid;
elseif(my_status=2)
then
update users set score=score+20 where id=userid;
else
update users set score=score+30 where id=userid;
end if;
end;调用程之前的users表的数据如图(13),调用 call test8(1); 及运行结果图(14):
图(14) 八、存储过程循环语句
(1)、while语句的基本结构 while(表达式) do ...... end while; (2)、示例 create procedure test9()
begin
declare i int default 0;
while(i<10) do
begin
select i;
set i=i+1;
insert into test1(id) values(i);
end;
end while;
end;调用及运行结果结果如图(15)和图(16):
图(15) 图(16)
repeat...until...end repeat; (2)、示例 需求:给test1表中的id字段插入数据,从1到10 create procedure test10()
begin
declare i int default 0;
repeat
begin
select i;
set i=i+1;
insert into test1(id) values(i);
end;
until i>=10 -- 如果i>=10,则跳出循环
end repeat;
end;调用及运行结果结果如图(17)和图(18)
图(17)
图(18) 九、存储过程游标的使用 1、什么是游标 create procedure test11()
begin
declare stopflag int default 0;
declare username VARCHAR(32);
-- 创建一个游标变量,declare 变量名 cursor ...
declare username_cur cursor for select name from users where id%2=0;
-- 游标是保存查询结果的临时区域
-- 游标变量username_cur保存了查询的临时结果,实际上就是结果集
-- 当游标变量中保存的结果都查询一遍(遍历),到达结尾,将变量stopflag设置为1,用于循环中判断是否结束
declare continue handler for not found set stopflag=1;
open username_cur; -- 打卡游标
fetch username_cur into username; -- 游标向前走一步,取出一条记录放到变量username中
while(stopflag=0) do -- 如果游标还没有结尾,就继续
begin
-- 在用户名前门拼接 '_cur' 字符串
update users set name=CONCAT(username,'_cur') where name=username;
fetch username_cur into username;
end;
end while; -- 结束循环
close username_cur; -- 关闭游标
end;调用结果如图(19): |
