MYSQL存储过程心得讲解与实例

4 篇文章 0 订阅
4 篇文章 0 订阅

# 一、存储过程简介
```
SQL语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,
经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
```
## 二、存储过程的特点
### 优点
```
1、能完成较复杂的判断和运算
2、可编程行强,灵活
3、SQL编程的代码可重复使用
4、执行的速度相对快一些
5、减少网络之间的数据传输,节省开销    
```
### 缺点
```
不易维护,阅读性差
```
## 三、创建一个简单的存储过程
1、创建存储过程的简单语法
``` sql
create procedure 名称()
begin
.........
end
```
2、创建一个简单的存储过程
```
create procedure testa()
begin
    select * from users;
    select * from orders;
end;
```
3、调用存储过程
```
call testa();  
```
## 四、存储过程的变量
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、概括
```
1.变量的声明使用declare,一句declare只声明一个变量,变量必须先声明后使用;
2.变量具有数据类型和长度,与mysql的SQL数据类型保持一致,因此甚至还能制定默认值、字符集和排序规则等;
3.变量可以通过set来赋值,也可以通过select into的方式赋值;
4.变量需要返回,可以使用select语句,如:select 变量名。
```
## 五、变量的作用域
 1、变量作用域说明:
```
1.存储过程中变量是有作用域的,作用范围在begin和end块之间,end结束变量的作用范围即结束。
2.需要多个块之间传值,可以使用全局变量,即放在所有代码块之前
3.传参变量是全局的,可以在多个块之间起作用
```
2、通过一个实例来验证变量的作用域
注意:存储过程中变量的作用域,作用范围在begin和end块之间,end结束变量的作用范围即结束

## 六、存储过程参数
1、基本语法
```
create procedure 名称([IN|OUT|INOUT] 参数名 参数数据类型 )
begin
.........
end
```
存储过程的参数类型有:IN,OUT,INOUT,下面分别介绍这个三种类型:
2、存储过程的传出参数IN
说明:
```        
1、传入参数:类型为in,表示该参数的值必须在调用存储过程事指定,如果不显示指定为in,那么默认就是in类型。
2、IN类型参数一般只用于传入,在调用过程中一般不作为修改和返回
3、如果调用存储过程中需要修改和返回值,可以使用OUT类型参数
```
3、存储过程的传出参数out
说明:
```
1、传出参数:在调用存储过程中,可以改变其值,并可返回;
2、out是传出参数,不能用于传入参数值;
3、调用存储过程时,out参数也需要指定,但必须是变量,不能是常量;
4、如果既需要传入,同时又需要传出,则可以使用INOUT类型参数
```
4、存储过程的可变参数INOUT
说明:
```
1、可变变量INOUT:调用时可传入值,在调用过程中,可修改其值,同时也可返回值;
2、INOUT参数集合了IN和OUT类型的参数功能;
3、INOUT调用时传入的是变量,而不是常量;
```

## 七、存储过程条件语句
1、基本结构
(1)、条件语句基本结构:
 ```
if() then...else...end if;
```   
(2)、多条件判断语句:
```
if() then...
elseif() then...
else ...
end if;
```   
2、实例
实例1:编写存储过程,如果用户userId是偶数则返回username,否则返回userId
```
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;
```
实例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;
```
## 八、存储过程循环语句
 1、while语句
while语句的基本结构
```
while(表达式) do 
   ......  
end while;
```
实例:
```
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;
```

2、repeat语句
repeat语句基本的结构:
``` 
repeat...until...end repeat;
```
实例:
```
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;
```

概括:
   until判断返回逻辑真或者假,表达式可以是任意返回真或者假的表达式,只有当until语句为真是,循环结束。

## 九、存储过程游标的使用
1、什么是游标
    游标是保存查询结果的临时区域
2、示例
    需求:编写存储过程,使用游标,把users表中 id为偶数的记录逐一更新用户名
```
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;
```

## 十、自定义函数
1、什么是自定义函数
    函数与存储过程最大的区别是函数必须有返回值,否则会报错
2、说明:
```
1.创建函数使用create function 函数名(参数) returns 返回类型;
2.函数体放在begin和end之间;
3.returns指定函数的返回值;
4.函数调用使用select getusername()。
```
3、实例
 需求:根据userid,获取accoutid,id,name组合成UUID作为用户的唯一标识
```
  create function getuuid(userid int) returns varchar(64)
    reads sql data  -- 从数据库中读取数据,但不修改数据
    begin
        declare uuid varchar(64) default '';
        select concat(accontid,'_',id,'_',name) into uuid from users where id=userid;
        return uuid;
    end;
```
## 十一、触发器
1、什么是触发器?
    触发器与函数、存储过程一样,触发器是一种对象,它能根据对表的操作时间,触发一些动作,这些动作可以是insert,update,delete等修改操作。
2、实例
```
create trigger tr_users_insert after insert on users
    for each row 
    begin 
        insert into oplog(userid,username,action,optime)
        values(NEW.id,NEW.name,'insert',now());
    end;
```
3、总结
```
1、创建触发器使用create trigger 触发器名
2、什么时候触发?after insert on users,除了after还有before,是在对表操作之前(before)或者之后(after)触发动作的。
3、对什么操作事件触发? after insert on users,操作事件包括insert,update,delete等修改操作;
4、对什么表触发? after insert on users
5、影响的范围?for each row
```

## 十二、流程控制
case分支
```
case ...
when ... then....
when.... then....
else ... 
end case;
```
实例
```
 create procedure testcate(userid int)
    begin 
        declare my_status int default 0;
        select status into my_status from users where id=userid;
 
        case my_status
            when 1 then update users set score=10 where id=userid;
            when 2 then update users set score=20 where id=userid;
            when 3 then update users set score=30 where id=userid;
            else update users set score=40 where id=userid;
        end case;
    end;
```

## 十三、存储过程+event(事件)

 

个人博客:
名称:纯洁的麦田
链接:http://www.idearyou.cn/
描述:争取哪一天做上架构师
公众号:纯洁的麦田

另外:个人公众号,每天有新java文章,还有中高级面试题分享

  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值