设为首页 收藏本站
查看: 924|回复: 0

[经验分享] MySQL存储过程的创建及调用

[复制链接]

尚未签到

发表于 2017-12-13 15:48:45 | 显示全部楼层 |阅读模式

阅读目录:MySQL存储过程_创建-调用-参数



  • 存储过程:SQL中的“脚本”
    创建存储过程

    调用存储过程

    存储过程体

    语句块标签



  • 存储过程的参数
    in:向过程里传参

    out:过程向外传参值

    inout:in and out



#SQL语句:先编译后执行

存储过程(Stored Procedure):

  一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。


优点(为什么要用存储过程?):

  ①将重复性很高的一些操作,封装到一个存储过程中,简化了对这些SQL的调用

  ②批量处理:SQL+循环,减少流量,也就是“跑批”

  ③统一接口,确保数据的安全

相对于oracle数据库来说,MySQL的存储过程相对功能较弱,使用较少。


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

  >存储过程就是具有名字的一段代码,用来完成一个特定的功能。

  >创建的存储过程保存在数据库的数据字典中。

1、创建存储过程

  

CREATE
[DEFINER

= { user | CURRENT_USER }]  
 PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body

  

  
proc_parameter:
[ IN

| OUT | INOUT ] param_name type  

  
characteristic:
  COMMENT
'string'  | LANGUAGE SQL
| [NOT] DETERMINISTIC| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }| SQL SECURITY { DEFINER | INVOKER }  

  
routine_body:
  
  Valid SQL routine statement
  

  
[begin_label:] BEGIN
  
  [statement_list]
  
    ……
  
END [end_label]
  

#创建数据库,备份数据表用于示例操作

  

mysql> create database db1;  
mysql
> use db1;  
mysql
> create table PLAYERS as select * from TENNIS.PLAYERS;  
mysql
> create table MATCHES  as select * from TENNIS.MATCHES;  


示例:创建一个存储过程,删除给定球员参加的所有比赛

  

mysql> delimiter $$  #将语句的结束符号从分号;临时改为两个$$(可以是自定义)  
mysql
> CREATE PROCEDURE delete_matches(IN p_playerno INTEGER)  -> BEGIN
  ->   DELETE FROM MATCHES
  ->    WHERE playerno = p_playerno;
  -> END$$
  
Query OK,
0 rows affected (0.01 sec)  

  
mysql
> delimiter ;  #将语句的结束符号恢复为分号  


解析:

  默认情况下,存储过程和默认数据库相关联,如果想指定存储过程创建在某个特定的数据库下,那么在过程名前面加数据库名做前缀;

  在定义过程时,使用DELIMITER $$ 命令将语句的结束符号从分号 ; 临时改为两个$$,使得过程体中使用的分号被直接传递到服务器,而不会被客户端(如mysql)解释。


2、调用存储过程:call sp_name[(传参)];

  

mysql> select * from MATCHES;  

+---------+--------+----------+-----+------+  
| MATCHNO | TEAMNO | PLAYERNO | WON | LOST |
  
+---------+--------+----------+-----+------+
  
|       1 |      1 |        6 |   3 |    1 |
  
|       7 |      1 |       57 |   3 |    0 |
  
|       8 |      1 |        8 |   0 |    3 |
  
|       9 |      2 |       27 |   3 |    2 |
  
|      11 |      2 |      112 |   2 |    3 |
  
+---------+--------+----------+-----+------+
  
5 rows in set (0.00 sec)
  

  
mysql
> call delete_matches(57);  
Query OK,
1 row affected (0.03 sec)  

  
mysql
> select * from MATCHES;  

+---------+--------+----------+-----+------+  
| MATCHNO | TEAMNO | PLAYERNO | WON | LOST |
  
+---------+--------+----------+-----+------+
  
|       1 |      1 |        6 |   3 |    1 |
  
|       8 |      1 |        8 |   0 |    3 |
  
|       9 |      2 |       27 |   3 |    2 |
  
|      11 |      2 |      112 |   2 |    3 |
  
+---------+--------+----------+-----+------+
  
4 rows in set (0.00 sec)
  


解析:

  在存储过程中设置了需要传参的变量p_playerno,调用存储过程的时候,通过传参将57赋值给p_playerno,然后进行存储过程里的SQL操作。


3、存储过程体

  >存储过程体包含了在过程调用时必须执行的语句,例如:dml、ddl语句,if-then-else和while-do语句、声明变量的declare语句等

  >过程体格式:以begin开始,以end结束(可嵌套)

  

BEGIN  
  BEGIN
  
    BEGIN
  
      statements;
  
    END
  
  END
  
END
  


注意:每个嵌套块及其中的每条语句,必须以分号结束,表示过程体结束的begin-end块(又叫做复合语句compound statement),则不需要分号。


4、为语句块贴标签

  

[begin_label:] BEGIN  
  [statement_list]
  
END [end_label]
  


例如:

  

label1: BEGIN  
  label2: BEGIN
  
    label3: BEGIN
  
      statements;
  
    END label3 ;
  
  END label2;
  
END label1
  


标签有两个作用:

  ①增强代码的可读性

  ②在某些语句(例如:leave和iterate语句),需要用到标签



二、存储过程的参数

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

3种参数类型:

  IN输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)

  OUT输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)

  INOUT输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)


1、in输入参数

  

mysql> delimiter $$  
mysql
> create procedure in_param(in p_in int)-> begin->   select p_in;->   set p_in=2;->    select P_in;-> end$$  
mysql
> delimiter ;  

  mysql
> set @p_in=1;  

  mysql
> call in_param(@p_in);  

+------+  
| p_in |
  
+------+
  
|    1 |
  
+------+
  

  +------+
  
| P_in |
  
+------+
  
|    2 |
  
+------+
  

  
mysql
> select @p_in;  

+-------+  
| @p_in |
  
+-------+
  
|     1 |
  
+-------+
  


#以上可以看出,p_in在存储过程中被修改,但并不影响@p_id的值,因为前者为局部变量、后者为全局变量。


2、out输出参数

  

mysql> delimiter //  
mysql
> create procedure out_param(out p_out int)->   begin->     select p_out;->     set p_out=2;->     select p_out;->   end-> //  
mysql
> delimiter ;  

  
mysql
> set @p_out=1;  

  
mysql
> call out_param(@p_out);  

+-------+  
| p_out |
  
+-------+
  
|  NULL |
  
+-------+
  
  
#因为out是向调用者输出参数,不接收输入的参数,所以存储过程里的p_out为null  
+-------+
  
| p_out |
  
+-------+
  
|     2 |
  
+-------+
  

  
mysql> select @p_out;
  
+--------+
  
| @p_out |
  
+--------+
  
|      2 |
  
+--------+
  
  #调用了out_param存储过程,输出参数,改变了p_out变量的值
  



3、inout输入参数

  

mysql> delimiter $$  
mysql
> create procedure inout_param(inout p_inout int)->   begin->     select p_inout;->     set p_inout=2;->     select p_inout;->   end-> $$  
mysql
> delimiter ;  

  
mysql
> set @p_inout=1;  

  
mysql
> call inout_param(@p_inout);  

+---------+  
| p_inout |
  
+---------+
  
|       1 |
  
+---------+
  

  
+---------+
  
| p_inout |
  
+---------+
  
|       2 |
  
+---------+
  

  
mysql
> select @p_inout;  

+----------+  
| @p_inout |
  
+----------+
  
|        2 |
  
+----------+
  


#调用了inout_param存储过程,接受了输入的参数,也输出参数,改变了变量


注意:

  ①如果过程没有参数,也必须在过程名后面写上小括号

    例:CREATE PROCEDURE sp_name ([proc_parameter[,...]]) ……

  ②确保参数的名字不等于列的名字,否则在过程体中,参数名被当做列名来处理

墙裂建议:



  >输入值使用in参数;

  >返回值使用out参数;

  >inout参数就尽量的少用。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-423707-1-1.html 上篇帖子: 怎么通过 Mysql 实现数据同步呢? 下篇帖子: 允许远程链接mysql,开放3306端口
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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