系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 数据库 > Mysql > 详细页面

mysql存储过程原理与使用方法详解

时间:2019-12-22来源:系统城作者:电脑系统城

本文实例讲述了mysql存储过程原理与使用方法。分享给大家供大家参考,具体如下:

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

存储过程的优点

#1. 用于替代程序写的SQL语句,实现程序与sql解耦

#2. 可以通过直接修改存储过程的方式修改业务逻辑(或bug),而不用重启服务器

#3. 执行速度快,存储过程经过编译之后会比单独一条一条执行要快

#4. 减少网络传输,尤其是在高并发情况下这点优势大,存储过程直接就在数据库服务器上跑,所有的数据访问都在服务器内部进行,不需要传输数据到其它终端。

存储过程的缺点

1.SQL本身是一种结构化查询语言,加上了一些控制(赋值、循环和异常处理等),但不是OO的,本质上还是过程化的,面对复杂的业务逻辑,过程化的处理会很吃力。这一点算致命伤,即只能应用在逻辑简单的业务上。

2.不便于调试。基本上没有较好的调试器,很多时候是用print来调试,但用这种方法调试长达数百行的存储过程简直是噩梦。好吧,这一点不算啥,C#/java一样能写出噩梦般的代码。

3.没办法应用缓存。虽然有全局临时表之类的方法可以做缓存,但同样加重了数据库的负担。如果缓存并发严重,经常要加锁,那效率实在堪忧。

4.无法适应数据库的切割(水平或垂直切割)。数据库切割之后,存储过程并不清楚数据存储在哪个数据库中。

无参的存储过程


 
  1. delimiter //
  2. create procedure p1()
  3. BEGIN
  4. select * from blog;
  5. INSERT into blog(name,sub_time) values("xxx",now());
  6. END //
  7. delimiter ;
  8.  

 
  1. #在mysql中调用
  2. call p1()
  3.  

 
  1. #在python中基于pymysql调用
  2. cursor.callproc('p1')
  3. print(cursor.fetchall())
  4.  

有参的存储过程

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

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

带in的存储过程


 
  1. mysql> select * from emp;
  2. +----+----------+-----+--------+
  3. | id | name | age | dep_id |
  4. +----+----------+-----+--------+
  5. | 1 | zhangsan | 18 | 1 |
  6. | 2 | lisi | 19 | 1 |
  7. | 3 | egon | 20 | 2 |
  8. | 5 | alex | 18 | 2 |
  9. +----+----------+-----+--------+
  10. 4 rows in set (0.30 sec)
  11. mysql> delimiter //
  12. mysql> create procedure p2(in n1 int, in n2 int)
  13. -> begin
  14. -> select * from emp where id >n1 and id <n2;
  15. -> end //
  16. Query OK, 0 rows affected (0.28 sec)
  17. mysql> delimiter ;
  18. mysql> call p2(1,3)
  19. -> ;
  20. +----+------+-----+--------+
  21. | id | name | age | dep_id |
  22. +----+------+-----+--------+
  23. | 2 | lisi | 19 | 1 |
  24. +----+------+-----+--------+
  25. 1 row in set (0.07 sec)
  26. Query OK, 0 rows affected (0.07 sec)
  27.  

 
  1. #在python中基于pymysql调用
  2. cursor.callproc('p2',(1,3))
  3. print(cursor.fetchall())
  4.  

带有out


 
  1. mysql> delimiter //
  2. mysql> create procedure p3( in n1 int, out res int)
  3. -> begin
  4. -> select * from emp where id >n1;
  5. -> set res=1;
  6. -> end //
  7. Query OK, 0 rows affected (0.28 sec)
  8. mysql> delimiter ;
  9. mysql> set @res=0;
  10. Query OK, 0 rows affected (0.00 sec)
  11. mysql> call p3(3,@res);
  12. +----+------+-----+--------+
  13. | id | name | age | dep_id |
  14. +----+------+-----+--------+
  15. | 5 | alex | 18 | 2 |
  16. +----+------+-----+--------+
  17. 1 row in set (0.00 sec)
  18. Query OK, 0 rows affected (0.01 sec)
  19. mysql> select @res;
  20. +------+
  21. | @res |
  22. +------+
  23. | 1 |
  24. +------+
  25. 1 row in set (0.00 sec)
  26.  

 
  1. #在python中基于pymysql调用
  2. cursor.callproc('p3',(3,0)) #0相当于set @res=0
  3. print(cursor.fetchall()) #查询select的查询结果
  4. cursor.execute('select @_p3_0,@_p3_1;') #@p3_0代表第一个参数,@p3_1代表第二个参数,即返回值
  5. print(cursor.fetchall())
  6.  

带有inout的例子


 
  1. delimiter //
  2. create procedure p4(
  3. inout n1 int
  4. )
  5. BEGIN
  6. select * from blog where id > n1;
  7. set n1 = 1;
  8. END //
  9. delimiter ;

 
  1. #在mysql中调用
  2. set @x=3;
  3. call p4(@x);
  4. select @x;

 
  1. #在python中基于pymysql调用
  2. cursor.callproc('p4',(3,))
  3. print(cursor.fetchall()) #查询select的查询结果
  4. cursor.execute('select @_p4_0;')
  5. print(cursor.fetchall())
  6.  

 事务


 
  1. #介绍
  2. delimiter //
  3. create procedure p4(
  4. out status int
  5. )
  6. BEGIN
  7. 1. 声明如果出现异常则执行{
  8. set status = 1;
  9. rollback;
  10. }
  11. 开始事务
  12. -- 由秦兵账户减去100
  13. -- 方少伟账户加90
  14. -- 张根账户加10
  15. commit;
  16. 结束
  17. set status = 2;
  18. END //
  19. delimiter ;
  20. #实现
  21. delimiter //
  22. create PROCEDURE p5(
  23. OUT p_return_code tinyint
  24. )
  25. BEGIN
  26. DECLARE exit handler for sqlexception
  27. BEGIN
  28. -- ERROR
  29. set p_return_code = 1;
  30. rollback;
  31. END;
  32. DECLARE exit handler for sqlwarning
  33. BEGIN
  34. -- WARNING
  35. set p_return_code = 2;
  36. rollback;
  37. END;
  38. START TRANSACTION;
  39. DELETE from tb1; #执行失败
  40. insert into blog(name,sub_time) values('yyy',now());
  41. COMMIT;
  42. -- SUCCESS
  43. set p_return_code = 0; #0代表执行成功
  44. END //
  45. delimiter ;
  46.  

 
  1. #在mysql中调用存储过程
  2. set @res=123;
  3. call p5(@res);
  4. select @res;
  5.  

 
  1. #在python中基于pymysql调用存储过程
  2. cursor.callproc('p5',(123,))
  3. print(cursor.fetchall()) #查询select的查询结果
  4. cursor.execute('select @_p5_0;')
  5. print(cursor.fetchall())
  6.  

存储过程的执行

 mysql中执行


 
  1. -- 无参数
  2. call proc_name()
  3. -- 有参数,全in
  4. call proc_name(1,2)
  5. -- 有参数,有in,out,inout
  6. set @t1=0;
  7. set @t2=3;
  8. call proc_name(1,2,@t1,@t2)
  9.  

 pymsql中执行


 
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import pymysql
  4. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
  5. cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
  6. # 执行存储过程
  7. cursor.callproc('p1', args=(1, 22, 3, 4))
  8. # 获取执行完存储的参数
  9. cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")
  10. result = cursor.fetchall()
  11. conn.commit()
  12. cursor.close()
  13. conn.close()
  14. print(result)
  15.  

删除存储过程


 
  1. drop procedure proc_name;
  2.  

更多关于MySQL相关内容感兴趣的读者可查看本站专题:《MySQL存储过程技巧大全》、《MySQL常用函数大汇总》、《MySQL日志操作技巧大全》、《MySQL事务操作技巧汇总》及《MySQL数据库锁相关技巧汇总》

希望本文所述对大家MySQL数据库计有所帮助。

分享到:

相关信息

  • MySQL的核心查询语句详解

    一、单表查询 1、排序 2、聚合函数 3、分组 4、limit 二、SQL约束 1、主键约束 2、非空约束 3、唯一约束 4、外键约束 5、默认值 三、多表查询 1、内连接 1)隐式内连接: 2)显式内连接: 2、外连接 1)左外连接 2)右外连接 四...

    2023-10-30

  • Mysql中如何删除表重复数据

    Mysql删除表重复数据 表里存在唯一主键 没有主键时删除重复数据 Mysql删除表中重复数据并保留一条 准备一张表 用的是mysql8 大家自行更改 创建表并添加四条相同的数据...

    2023-10-30

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载