MySQl的视图、触发器和存储过程

3.存储过程

储蓄过程相当于编程语言调用函数存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql语句。

优点 1.用于替代程序写的SQL语句,实现程序与sql解耦
2.基于网络传输,传别名的数据量小,而直接传sql数据量大
缺点 程序员扩展功能不方便

PS:程序与数据库结合使用的三种方式比较

方式 python MySQL 优点 缺点
方式一 调用存储过程 编写存储过程 解耦合 但是人为因素导致扩展性低
方式二 编写纯生SQL do not care 综合扩展性高 效率低于方式一,占用网络
方式三 ORM->纯生SQL do not care 开发效率高,可维护性好
可扩展性好,最常用
效率最低,占网络

创建简单的储存过程

准备表

#假设当前所在的数据库为myschool

create table teacher(  
    tid int primary key auto_increment,  
    tname char(10) 
); 

insert into teacher values 
    (1,"张磊老师"), 
    (2,"李平老师"), 
    (3,"邓晓庆老师"), 
    (4,"朱云海老师"), 
    (5,"李杰老师") 
; 

无参数

#在shlle的MySQL的myschool库下执行以下创建代码

delimiter //  #delimiter暂时修改结束符号;
create procedure p1()  #形式和函数类似,过程名就叫p1
begin
    select * from db7.teacher;  #相关sql命令
end //
delimiter ; #将结束符号修改回来

# MySQL中调用,直接触发相关储存过程的执行
call p1();

+-----+-----------------+
| tid | tname           |
+-----+-----------------+
|   1 | 张磊老师        |
|   2 | 李平老师        |
|   3 | 邓晓庆老师      |
|   4 | 朱云海老师      |
|   5 | 李杰老师        |
+-----+-----------------+
5 rows in set (0.08 sec)

# Python中调用方式
# cursor.callproc('p1')
# cursor.fetchall()

import pymysql
#建立链接
conn = pymysql.connect(
    host="127.0.0.1",
    port=3306,
    user="root",
    password="abc123",
    db="myschool",
    charset="utf8"
)
#拿游标
cursor = conn.cursor(pymysql.cursors.DictCursor)#基于字典的游标
cursor.callproc("p1")  #调用存储过程
print(cursor.fetchall()) #全取出
#关闭游标和链接
cursor.close()
conn.close()

#运行结果
[{'tid': 1, 'tname': '张磊老师'}, {'tid': 2, 'tname': '李平老师'}, {'tid': 3, 'tname': '邓晓庆老师'}, {'tid': 4, 'tname': '朱云海老师'}, {'tid': 5, 'tname': '李杰老师'}]

补充:对于存储过程,可以接收参数,其参数有三类

  • in 仅用于传入参数用
  • out 仅用于返回值用
  • inout 既可以传入又可以当作返回值(inout的使用就是in 和out 的结合,很简单)

有参数

###in 代表传入的参数,out为返回值
delimiter //
create procedure p2(in n1 int,in n2 int,out res int) 
begin
    select * from teacher where tid > n1 and tid < n2;
    set res = 1;
end //
delimiter ;


# MySQL中调用
set @x=0; #用于接受返回值
call p2(2,4,@x); 
+-----+-----------------+
| tid | tname           |
+-----+-----------------+
|   3 | 邓晓庆老师      |
+-----+-----------------+
1 row in set (0.04 sec)

select @x; #查看结果
+------+
| @x   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)


# Python中调用

import pymysql
#建立链接
conn = pymysql.connect(
    host="127.0.0.1",
    port=3306,
    user="root",
    password="abc123",
    db="myschool",
    charset="utf8"
)
#拿游标
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)#基于字典的游标,cursor=可以不写
cursor.callproc("p2",(2,4,0))  #调用存储过程,0代表初需要传出的值设定初始值!
# 这里,会自动产生参数,对应的值为@_p2_0=2,@_p2_1=4,@_p2_2=0   0相当于set @res=0
print(cursor.fetchall())
cursor.execute('select @_p2_2') #相当于shell里面执行select @x
print(cursor.fetchall()) #全取出
#关闭游标和链接
cursor.close()
conn.close()

#运行结果
[{'tid': 3, 'tname': '邓晓庆老师'}]
[{'@_p2_2': 1}]


### inout表示由可传入又可传出
delimiter //
create procedure p3(inout n1 int)
begin
    select * from teacher where cid > n1;
    set n1 = 1;
end //
delimiter ;

#在mysql中调用
set @x=0;
call p3(@x);
+-----+-----------------+
| tid | tname           |
+-----+-----------------+
|   1 | 张磊老师        |
|   2 | 李平老师        |
|   3 | 邓晓庆老师      |
|   4 | 朱云海老师      |
|   5 | 李杰老师        |
+-----+-----------------+
5 rows in set (0.00 sec)

select @x;
+------+
| @x   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)


#在python中基于pymysql调用
import pymysql

conn = pymysql.connect(
    host = "127.0.0.1",
    port = 3306,
    user = "root",
    password = "abc123",
    db = "myschool",
    charset="utf8"
)

cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.callproc('p3',(0,)) #必须写成元组的形式,在后面加个逗号,与(0)这种形式区分开!
print(cursor.fetchall()) #查询select的查询结果
cursor.execute('select @_p3_0;') #查看返回值
print(cursor.fetchall())

cursor.close()
conn.close()

#执行结果 
[{'tid': 1, 'tname': '张磊老师'}, {'tid': 2, 'tname': '李平老师'}, {'tid': 3, 'tname': '邓晓庆老师'}, {'tid': 4, 'tname': '朱云海老师'}, {'tid': 5, 'tname': '李杰老师'}]
[{'@_p3_0': 1}]


总结:执行储存过程

shell下进入MySQL

call proc_name()-- 无参数

call proc_name(1,2)-- 有参数,全in

-- 有参数,有in,out,inout
set @t1=0;
set @t2=3;
call proc_name(1,2,@t1,@t2)

删除储存过程

drop procedure p1;
drop procedure p2;
drop procedure p3;
posted @ 2018-04-25 21:09  哈哈大圣  阅读(139)  评论(0编辑  收藏  举报