存储过程简介: 能完成比较复杂的判断和运算 可编程性强,灵活 sql编程的代码可以重复使用 执行速度相对会快一些 减少网络之间的数据传输,节省开销准备工作: dilimiter 可以修改sql语句的结尾结束符。修改分号为其他符号, 因为存储过程和函数中有多个分号,多以需要用dilimiter修改结束符本博客使用测试数据库为mysql官方测试数据库sakila,mysql官网可下载
mysql简单存储过程
1,最简单的存储过程
需求:查询actor表中id为偶数的actor信息
delimiter $$
create procedure sel_even_actor()
begin
select * from actor where actor_id%2 = 0;
end;
$$
delimiter;
call sel_even_actor();
总结:
创建语法:create procedure procedure_Name;
包含一个以上的代码块,代码块要用begin,end之间包含;
在命令行中创建的情况下,需要使用定义分隔符delimiter $$,
创建结束并且要修改回来
2,存储过程中定义变量
需求:取出actor_id = 28的演员名
delimiter $$
create procedure sel_actorname_28()
begin
//定义变量,用来保存需要查询的名字
declare actorname_28 varchar(64) default "";
//set可以给变量赋值
set actorname_28 = 'NiuShao';
//存储过程中也可以用into赋值
select concat(first_name,'-',last_name) as name into actorname_28 from actor where actor_id=28;
//显示查出的值
select actorname_28;
end;
$$
delimiter;
call sel_even_actor();
总结:
变量的声明使用declare语句,一个declare只能声明一个变量,变量必须先声明后使用
变量具有数据类型和长度,和myuql的sql数据类型保持一致,因此也可以指定默认值,字符集和排序规则
变量可以用set进行赋值,也可以用select into 的方式赋值
变量如果需要返回,可以使用select语句,例如:select 变量名
需求:取出actor,film表的行数以及actor表名字用A开头的演员和film中用B开头的电影
delimiter $$
create procedure sel_actor_film()
begin
begin
declare a_sum int default 0;
declare f_sum int default 0;
select count(*) into a_sum from actor;
select count(*) into f_sum from film;
select a_sum,f_sum;
end;
begin
declare a_a varchar(64) default "";
declare f_a varchar(64) default "";
select concat(first_name,'-',last_name) into a_a from actor where first_name like "A%";
select title into f_a from film where title like 'A%';
select a_a,f_a;
end;
end;
$$
delimiter ;
call sel_actor_film();//这里第二个代码块因为超过了一行,调用的时候无法显示。所以变量只能保存一个数据来输出
注意:变量是有作用域的,作用范围在begin和end块之间,end结束变量的作用范围即结束
需要多个块之间传递值,可以使用全局变量,即放在所有代码块之前
传参变量是全局的,可以在多个代码块之间起作用
3,存储过程的传入参数IN
需求:传入参数actor_id,取出该id下的演员名字
delimiter $$
create procedure sel_actorname_in(actorid int)
begin
declare actorname varchar(64) default "";
select concat(first_name,'-',last_name) as name into actorname from actor where actor_id = actorid;
select actorname;
end;
$$
delimiter ;
call sel_actorname_in(28);
总结:传入参数,类型为IN,表示该参数的值必须在调用存储过程的时候指定,如果不是指定为IN,默认就是IN类型
IN类型参数一般只用于传入,在调用的过程中一般不做修改和返回
如果调用存储过程中需要修改和返回值,可以使用out类型参数
4,存储过程的传入参数OUT
需求:传入film_id,输出电影title
delimiter $$
create procedure sel_film_out(in id int,out name varchar(64))
begin
select title into name from film where film_id=id;
select name;
end;
$$
delimiter ;
set @name=""; //mysql中命令行定义变量
call sel_film_out(1,@name); //mysql中命令行调用变量
归纳:
传出参数,在调用存储过程中,可以改变值,并且可以返回
out是传出参数,不能用于传入参数的值
调用存储过程时,out参数也需要指定,但必须是变量,不能是常量
如果既需要传入参数,同时有需要传出参数,可以使用INOUT类型参数
5,存储过程的可变参数INOUT
需求:传入file_id,同时传出title,file_id
delimiter $$
create procedure sel_film_inout(inout id int,inout name varchar(64))
begin
select film_id,title into id,name from film where film_id=id;
select id,name;
end;
$$
delimiter ;
set @name="";
set @id="28";
call sel_film_inout(@id,@name);
归纳:
可变变量inout,调用额时候可传入值,在调用过程中可以修改它的值,同时也能返回值
inout 参数集合了in和out类型的参数功能
inout调用的时候传入的是变量,而不是常量
6,存储过程中的条件语句
需求:编写存储过程,如果id为偶数,给我title。如果为奇数,给出id
delimiter $$
create procedure sel_film_if(IN id int)
begin
declare name varchar(32) default "";
if(id%2=0)
then
select title into name from film where film_id = id;
select name;
else
select id;
end if;
end;
$$
delimiter ;
call sel_film_if(29);
call sel_film_if(28);
归纳:
条件语句最基本的结构 if() then ……else……end if;
引申为 if()
then
……
elseif()
then
……
elseif()
then
……
end if;
if判断返回逻辑的真假,表达式可以是任意返回真假的表达式
7,while循环语句
需求:
创建只有id的表,并且插入一万条数据
create table test_while(
`id` int not null
);
delimiter $$
create procedure insert_test()
begin
declare i int default 0;
while(i<=10000) do
begin
select i;
set i = i+1;
insert into test_while(id)values(i);
end;
end while;
end;
$$
delimiter ;
call test_while();
归纳:
while语句最基本的结构
while()do
begin
end;
end while;
while判断返回逻辑的真假,表达式可以是任意返回真假的表达式
8,repeat循环语句
需求:同while的测试表,降序插入10000条语句
delimiter $$
create procedure insert_repeat()
begin
declare i int default 10001;
repeat
begin
select i;
set i = i-1;
insert into test_while(id)values(i);
end;
until i<0
end repeat;
end;
$$
delimiter ;
归纳:
repeat语句最基本的结构,repeat
begin
……
end;
untile……
end repeat;
until判断返回逻辑的真或者假,表达式可以是任意返回真或者i假的表达式,只有当until语句为真的时候,循环结束。
9,游标
简介:mysql中的游标,就是保存查询结果的临时内存区域
需求:编写存储过程,使用游标把film_id为偶数的记录加后缀
delimiter $$
create procedure film_cursor()
begin
//定义停止循环的变量
declare stopwhile int default 0;
//定义变量获取当前游标的值
declare name varchar(64);
//定义游标变量,保存当前查询结果
declare name_cursor cursor for select title from film where film_id%2=0;
//continue handler 是游标句柄,如果游标结束,则改变循环变量的值
declare continue handler for not found set stopwhile = 1;
//打开游标,也就是当前定义的游标变量
open name_cursor;
//获取当前游标变量,赋值给name
fetch name_cursor into name;
//循环修改
while (stopwhile=0) do
begin
update film set title = concat(name,'_NiuShao') where title = name;
fetch name_cursor into name;
end;
end while;
//关闭游标
close name_cursor;
end;
$$
delimiter ;
call film_cursor()
归纳:
定义游标变量,变量名后加 cursor
游标变量是一个select 语句赋值,fetch一次,查一次,直到查询结束,也就是游标句柄找不到。赋值用 for
使用游标需要开启游标和关闭游标