设为首页收藏本站

安徽论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 12035|回复: 0

详解MySQL存储过程的创建和调用

[复制链接]

110

主题

0

回帖

342

积分

中级会员

Rank: 3Rank: 3

积分
342
发表于 2022-3-26 10:59:19 | 显示全部楼层 |阅读模式
网站内容均来自网络,本站只提供信息平台,如有侵权请联系删除,谢谢!
目录


前言


存储过程(Stored Procedure):

一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。
优点(为什么要用存储过程?):
1.将重复性很高的一些操作,封装到一个存储过程中,简化了对这些SQL的调用
2.批量处理:SQL+循环,减少流量,也就是“跑批”
3.统一接口,确保数据的安全
相对于oracle数据库来说,MySQL的存储过程相对功能较弱,使用较少。

一、存储过程的创建和调用


  • 存储过程就是具有名字的一段代码,用来完成一个特定的功能。
  • 创建的存储过程保存在数据库的数据字典中。

1、创建存储过程
  1. CREATE
  2.     [DEFINER = { user | CURRENT_USER }]
  3.  PROCEDURE sp_name ([proc_parameter[,...]])
  4.     [characteristic ...] routine_body
  5. proc_parameter:
  6.     [ IN | OUT | INOUT ] param_name type
  7. characteristic:
  8.     COMMENT 'string'
  9.   | LANGUAGE SQL
  10.   | [NOT] DETERMINISTIC
  11.   | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  12.   | SQL SECURITY { DEFINER | INVOKER }
  13. routine_body:
  14.   Valid SQL routine statement
  15. [begin_label:] BEGIN
  16.   [statement_list]
  17.     ……
  18. END [end_label]
复制代码
#创建数据库,备份数据表用于示例操作
  1. mysql> create database db1;
  2. mysql> use db1;   
  3. mysql> create table PLAYERS as select * from TENNIS.PLAYERS;
  4. mysql> create table MATCHES  as select * from TENNIS.MATCHES;
复制代码
示例:创建一个存储过程,删除给定球员参加的所有比赛
  1. mysql> delimiter $$  #将语句的结束符号从分号;临时改为两个$$(可以是自定义)
  2. mysql> CREATE PROCEDURE delete_matches(IN p_playerno INTEGER)
  3.     -> BEGIN
  4.     ->   DELETE FROM MATCHES
  5.     ->    WHERE playerno = p_playerno;
  6.     -> END$$
  7. Query OK, 0 rows affected (0.01 sec)
  8. mysql> delimiter ;  #将语句的结束符号恢复为分号
复制代码
解析:
默认情况下,存储过程和默认数据库相关联,如果想指定存储过程创建在某个特定的数据库下,那么在过程名前面加数据库名做前缀;
在定义过程时,使用DELIMITER $$ 命令将语句的结束符号从分号 ; 临时改为两个$$,使得过程体中使用的分号被直接传递到服务器,而不会被客户端(如mysql)解释。

2、调用存储过程:call sp_name[(传参)];
  1. mysql> select * from MATCHES;
  2. +---------+--------+----------+-----+------+
  3. | MATCHNO | TEAMNO | PLAYERNO | WON | LOST |
  4. +---------+--------+----------+-----+------+
  5. |       1 |      1 |        6 |   3 |    1 |
  6. |       7 |      1 |       57 |   3 |    0 |
  7. |       8 |      1 |        8 |   0 |    3 |
  8. |       9 |      2 |       27 |   3 |    2 |
  9. |      11 |      2 |      112 |   2 |    3 |
  10. +---------+--------+----------+-----+------+
  11. 5 rows in set (0.00 sec)
  12. mysql> call delete_matches(57);
  13. Query OK, 1 row affected (0.03 sec)
  14. mysql> select * from MATCHES;
  15. +---------+--------+----------+-----+------+
  16. | MATCHNO | TEAMNO | PLAYERNO | WON | LOST |
  17. +---------+--------+----------+-----+------+
  18. |       1 |      1 |        6 |   3 |    1 |
  19. |       8 |      1 |        8 |   0 |    3 |
  20. |       9 |      2 |       27 |   3 |    2 |
  21. |      11 |      2 |      112 |   2 |    3 |
  22. +---------+--------+----------+-----+------+
  23. 4 rows in set (0.00 sec)
复制代码
解析:
在存储过程中设置了需要传参的变量p_playerno,调用存储过程的时候,通过传参将57赋值给p_playerno,然后进行存储过程里的SQL操作。

3、存储过程体


  • 存储过程体包含了在过程调用时必须执行的语句,例如:dml、ddl语句,if-then-else和while-do语句、声明变量的declare语句等
  • 过程体格式:以begin开始,以end结束(可嵌套)
  1. BEGIN
  2.   BEGIN
  3.     BEGIN
  4.       statements;
  5.     END
  6.   END
  7. END
复制代码
注意:每个嵌套块及其中的每条语句,必须以分号结束,表示过程体结束的begin-end块(又叫做复合语句compound statement),则不需要分号。

4、为语句块贴标签
  1. [begin_label:] BEGIN
  2.   [statement_list]
  3. END [end_label]
复制代码
例如:
  1. label1: BEGIN
  2.   label2: BEGIN
  3.     label3: BEGIN
  4.       statements;
  5.     END label3 ;
  6.   END label2;
  7. END label1
复制代码
标签有两个作用:

  • 增强代码的可读性
  • 在某些语句(例如:leave和iterate语句),需要用到标签

二、存储过程的参数

存储过程可以有0个或多个参数,用于存储过程的定义。
3种参数类型:

  • IN输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
  • OUT输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
  • INOUT输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)

1、in输入参数
  1. mysql> delimiter $$
  2. mysql> create procedure in_param(in p_in int)
  3.     -> begin
  4.     ->   select p_in;
  5.     ->   set p_in=2;
  6.     ->    select P_in;
  7.     -> end$$
  8. mysql> delimiter ;
  9. mysql> set @p_in=1;
  10. mysql> call in_param(@p_in);
  11. +------+
  12. | p_in |
  13. +------+
  14. |    1 |
  15. +------+
  16. +------+
  17. | P_in |
  18. +------+
  19. |    2 |
  20. +------+
  21. mysql> select @p_in;
  22. +-------+
  23. | @p_in |
  24. +-------+
  25. |     1 |
  26. +-------+
复制代码
#以上可以看出,p_in在存储过程中被修改,但并不影响@p_id的值,因为前者为局部变量、后者为全局变量。

2、out输出参数
  1. mysql> delimiter //
  2. mysql> create procedure out_param(out p_out int)
  3.     ->   begin
  4.     ->     select p_out;
  5.     ->     set p_out=2;
  6.     ->     select p_out;
  7.     ->   end
  8.     -> //
  9. mysql> delimiter ;
  10. mysql> set @p_out=1;
  11. mysql> call out_param(@p_out);
  12. +-------+
  13. | p_out |
  14. +-------+
  15. |  NULL |
  16. +-------+
  17.   #因为out是向调用者输出参数,不接收输入的参数,所以存储过程里的p_out为null
  18. +-------+
  19. | p_out |
  20. +-------+
  21. |     2 |
  22. +-------+
  23. mysql> select @p_out;
  24. +--------+
  25. | @p_out |
  26. +--------+
  27. |      2 |
  28. +--------+
  29.   #调用了out_param存储过程,输出参数,改变了p_out变量的值
复制代码
3、inout输入参数
  1. mysql> delimiter $$
  2. mysql> create procedure inout_param(inout p_inout int)
  3.     ->   begin
  4.     ->     select p_inout;
  5.     ->     set p_inout=2;
  6.     ->     select p_inout;
  7.     ->   end
  8.     -> $$
  9. mysql> delimiter ;
  10. mysql> set @p_inout=1;
  11. mysql> call inout_param(@p_inout);
  12. +---------+
  13. | p_inout |
  14. +---------+
  15. |       1 |
  16. +---------+
  17. +---------+
  18. | p_inout |
  19. +---------+
  20. |       2 |
  21. +---------+
  22. mysql> select @p_inout;
  23. +----------+
  24. | @p_inout |
  25. +----------+
  26. |        2 |
  27. +----------+
复制代码
#调用了inout_param存储过程,接受了输入的参数,也输出参数,改变了变量
注意:
1如果过程没有参数,也必须在过程名后面写上小括号
:CREATE PROCEDURE sp_name ([proc_parameter[,...]]) ……
2.确保参数的名字不等于列的名字,否则在过程体中,参数名被当做列名来处理
墙裂建议:

  • 输入值使用in参数;
  • 返回值使用out参数;
  • inout参数就尽量的少用。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
                                                        
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
免责声明
1. 本论坛所提供的信息均来自网络,本网站只提供平台服务,所有账号发表的言论与本网站无关。
2. 其他单位或个人在使用、转载或引用本文时,必须事先获得该帖子作者和本人的同意。
3. 本帖部分内容转载自其他媒体,但并不代表本人赞同其观点和对其真实性负责。
4. 如有侵权,请立即联系,本网站将及时删除相关内容。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表