存储过程

什么是存储过程

存储过程是一组任意的sql语句集合,存储在mysql中,调用存储过程时将会执行其包含的所有sql语句;与python中函数类似;

为什么使用存储过程

回顾触发器与视图都是为了简化应用程序中sql语句的书写,但是还是需要编写,而存储过程中可以包含任何的sql语句,包括视图,事务,流程控制等,这样一来,应用程序可以从sql语句中完全解放,mysql可以替代应用程序完成数据相关的的逻辑处理!

那我们以后都是用存储过程不就完了?

 

三种开发方式对比

1.应用程序仅负责业务逻辑编写,所有与数据相关的逻辑都交给mysql来完成,通过存储过程(推荐使用)

优点:

应用程序与数据处理完解耦合,一堆复杂的sql被封装成了一个简单的存储过程,考虑到网络环境因素,效率高

应用程序开发者不需要编写sql语句,开发效率高

缺点:

python语法与mysql语法区别巨大,学习成本高

并且各种数据库的语法大不相同,所以移植性非常差

应用程序开发者与BDA的跨部门沟通成本高,造成整体效率低

2.应用程序不仅编写业务逻辑,还需要编写所有的sql语句

优点:扩展性高,对于应用程序开发者而言,扩展性和维护性相较于第一种都有所提高

缺点:sql语句过于复杂,导致开发效率低,且需要考虑sql'优化问题

3.应用程序仅负责业务逻辑,sql语句的编写交给ORM框架,(常用解决方案)

优点:应用程序开发者不需要编写sql语句,开发效率高

缺点:执行效率低,由于需要将对象的操作转化为sql语句,且需要通过网络发送大量sql

创建存储过程

create procedure pro_name(p_Type p_name data_type)
begin
sql语句......流程控制
end

p_type 参数类型

  in 表示输入参数

  out 表示输出参数

  inout表示既能输入又能输出

p_name 参数名称

data_type 参数类型 可以是mysql支持的数据类型

创建存储过程

delimiter //
create procedure p1(in m int,in n int,out res int)
begin
    select *from student where chinese > m and chinese < n;
    #select *from student where chineseXXX > m and chinese < n; 修改错误的列名以测试执行失败
    set res = 100;
end//
delimiter ;

使用mysql使用存储过程

set @res = 0;
#调用存储过程
call p1(70,80,@res);
#查看执行结果
select @res;

python中调用存储过程

import pymysql
conn = pymysql.connect(
    user = "root",
    password = "root",
    database = "day48"
)
cur = conn.cursor(pymysql.cursors.DictCursor)
#调用存储过程
cur.callproc("p1",(70,80,0))
#p1是存储过程的名字,()是参数 每个位置设置变量@_p1_0 @_p1_1 @_p1_2
#获取执行结果
print(cur.fetchall())
cur.execute("select @_p1_2")
print(cur.fetchall())

此处pymysql会自动将参数都设置一个变量所以可以直接传入一个值,当然值如果作为输出参数的话,传入什么都无所谓!

删除存储过程

drop procedure 过程名称;

修改存储过程意义不大,不如删除重写!

查看存储过程

select name from mysql.proc where db = "day48" and type = "procedure";
#查看所有存储过程

#查看创建语句
show create procedure p1;

存储过程中的事务应用

存储过程中支持任何的sql语句包括事务!

案例:模拟转账中发送异常,进行回滚

elimiter //
create PROCEDURE p5(
    OUT p_return_code tinyint
)
BEGIN 
    DECLARE exit handler for sqlexception 
    BEGIN 

        set p_return_code = 1; 
        rollback; 
    END; 
    # exit 也可以换成continue 表示发送异常时继续执行
    DECLARE exit handler for sqlwarning 
    BEGIN 

        set p_return_code = 2; 
        rollback; 
    END; 
​
    START TRANSACTION; 
    update account set money = money - 1000 where id = 1;
    update account set moneys = money - 1000 where id = 1; # moneys字段导致异常
    COMMIT; 

    set p_return_code = 0; #0代表执行成功
​
END //
delimiter ;

调用

set @res=123;
call p5(@res);
select @res;

总结:抛开沟通成本,学习成本,存储过程无疑是效率最高的处理方式,面试会问,一些公司也有一些现存的存储过程,重点掌握!

 

posted @ 2018-11-26 19:05  msjaxuexi  阅读(379)  评论(0编辑  收藏  举报