存储过程

什么是mysql的存储过程
  简单来说就是把过程存储起来,什么过程呢,就是sql的执行过程 如果sql很多呢,也存储起来。
  所以存储过程就是把一系列要执行的sql存储起来(存在MySQL服务器上) 跟函数很像。

主要在什么地方用呢
  一般用于处理复杂逻辑 或多次对表操作
 为什么要用存储过程
  1 减少程序开发的工作量,程序开发者用的时候只需调用存储过程 ,另外存储过程可以重复使用,可减少数据库开发人员的工作量
  2 提高程序运行效率,.当对数据库进行复杂操作时(如对多个表进行 Update,Insert,Query,Delete 时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。这些操作,如果用程序来完成,就变成了一条条的 SQL 语句,可能要多次连接数据库。而换成存储,
    只需要连接一次数据库就可以了。
  3.增强了安全性:可设定只有某此用户才具有对指定存储过程的使用权

怎么用存储过程
  
delimiter $$
create procedure p1()
    BEGIN
    select * from app01_book;
    END $$
delimiter;

怎么调用呢

在msyql中 直接 call p1();

在python中呢

import  pymysql
db = pymysql.connect("localhost","root","","py_dj"cursorclass = pymysql.cursors.DictCursor) 
cursor
= db.cursor() cursor.callproc('p1',())#括号里传参 print(cursor.fetchall())

 

既然类似函数  那么函数有参数传入  有返回值

存储过程也有

  

#in          仅用于传入参数用
#out        仅用于返回值用
#inout     既可以传入又可以当作返回值

那么在定义阶段:
#in的用法,多个一样用逗号隔开
delimiter $$
create procedure p2(
    in n int
)
    BEGIN
    select * from app01_book where id>n;
    END $$
delimiter;

#out的用法
delimiter $$
create procedure p3(
    in n int,
    out res int
)
    BEGIN
    select * from app01_book where id>n;
    set res=8;
    END $$
delimiter;



#inout的用法
delimiter $$
create procedure p4(
    inout n int
)
    BEGIN
    select * from app01_book where id>n;
    set n=8;
    END $$
delimiter;

 

那么在调用阶段呢 

我们怎么调用呢

我先来看看mysql 变量

  

  1. 用户变量:以”@”开始,形式为”@变量名”。用户变量跟mysql客户端是绑定的,设置的变量,只对当前用户使用的客户端生效
  2. 全局变量:定义时,以如下两种形式出现,set GLOBAL 变量名  或者  set @@global.变量名,对所有客户端生效。只有具有super权限才可以设置全局变量
  3. 局部变量:作用范围在begin到end语句块之间。在该语句块里设置的变量。declare语句专门用于定义局部变量。set语句是设置不同类型的变量,包括会话变量和全局变量

在mysql中  

call p2(2);#可以直接调用p2


set @x=2
call p3(2,@x);#可以直接调用p3
select @x; #最后看看返回值


set @y=2
call p4(@y);#可以直接调用p4
select @y; #最后看看返回值

 

在python 中呢

import  pymysql
db = pymysql.connect("localhost","root","","py_dj" )
cursor = db.cursor()
# cursor.callproc('p1',())
# print(cursor.fetchall())

cursor.callproc('p2',(1,))
print(cursor.fetchall())
#((2, 'xx', Decimal('1212.00'), datetime.date(2018, 9, 15), 1, 1),)
cursor.callproc('p3',(1,2))
print(cursor.fetchall())
#((2, 'xx梅', Decimal('1212.00'), datetime.date(2018, 9, 15), 1, 1),)
cursor.execute('select @_p3_0,@_p3_1;') #@p3_0代表第一个参数@p3_1代表第二个参数,即返回值
print(cursor.fetchall())#((1, 8),)


cursor.callproc('p4',(0,)) \
#((1, 'yyyy', Decimal('2222.00'), datetime.date(2018, 9, 9), 2, 0), (2, 'xx梅', Decimal('1212.00'), datetime.date(2018, 9, 15), 1, 1))
print(cursor.fetchall())

cursor.execute('select @_p4_0;') 
print(cursor.fetchall())#((8,),)

 

最后建议  不经常变动的业务 且业务逻辑复杂 可以用存储过程  其他最后不要 用  ,维护 扩展 麻烦。

 

#查询存储过程
SELECT name FROM mysql.proc WHERE db='数据库名';
SELECT routine_name FROM information_schema.routines WHERE routine_schema='数据库名';
SHOW PROCEDURE STATUS WHERE db='数据库名';

 

#查看存储过程详细信息
SHOW CREATE PROCEDURE 数据库.存储过程名;
删除
DROP PROCEDURE xxx

posted @ 2018-12-10 17:52  孤月灵声  阅读(149)  评论(0编辑  收藏  举报