Home Database Mysql Tutorial 学习MYSQL存储过程_MySQL

学习MYSQL存储过程_MySQL

Jun 01, 2016 pm 02:01 PM
storage user

    一、 简介

    存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。

    虽然常用术语是存储过程(stored procedure),但MySQL实际上实现了两中类型,除了存储过程外,还有存储函数(stored routine),它们统称为存储例程。

     二、基本格式
1、存储过程
  CREATE PROCEDURE 过程名 ([过程参数[,...]])
  [特性 ...] 过程体

如创建: CEATE PROCEDURE p1 (a INT)

SELECT a;

调用一下:CALL p1(8);  

将显示:

+------+

| a    |

+------+

|    8 |

+------+

1 row in set (0.00 sec)
2、存储函数
  CREATE FUNCTION 函数名 ([函数参数[,...]])
  RETURNS 返回类型
  [特性 ...] 函数体

如创建:CREATE FUNCTION f1 (x INT)

RETURNS INT

RETURN x;       /* 过程函数一次只能返回一个值

调用一下:SELECT f1 (3);

将显示:

+-------+

| f1(3) |

+-------+

|     3 |

+-------+

1 row in set (0.00 sec)

3、过程参数
  [ IN | OUT | INOUT ] 参数名 参数类型
4、函数参数
  参数名 参数类型
5、返回类型
  有效的MySQL数据类型即可
6、过程体/函数体格式如下
BEGIN
有效的SQL语句
END

7、特性(一般不要求)
LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'

8、存储过程中参数的IN,OUT,INOUT类型

    存储过程可以接受输入参数,并把参数返回给调用方。不过,对于每个参数,需要声明其参数名、数据类型,还要指定此参数是用于向过程传递信息,还是从过程传回信息,或是二者兼有。

    为声明参数的作用,使用如下3个关键字之一:

˜ IN :  IN参数只用来向过程传递信息,为默认值。

 

˜ OUT : OUT参数只用来从过程传回信息。

 

˜ INOUT : INOUT参数可以向过程传递信息,如果值改变,则可再从过程外调用。

如果仅仅想把数据传给 MySQL 存储过程,那就使用“in” 类型参数;如果仅仅从 MySQL 存储过程返回值,那就使用“out” 类型参数;如果需要把数据传给 MySQL 存储过程,还要经过一些计算后再传回给我们,此时,要使用“inout” 类型参数。

对于任何声明为OUT或INOUT的参数,,当调用存储过程时需要在参数名前加上@符号,这样该参数就可以在过程外调用了。

 下面举三个实例:MySQL 存储过程 “in” 参数:跟 C 语言的函数参数的值传递类似, MySQL 存储过程内部可能会修改此参数,但对 in 类型参数的修改,对调用者(caller)来说是不可见的(not visible)。

create procedure pr_param_in(   in id int -- in 类型的 MySQL 存储过程参数)begin   if (id is not null) then      set id = id + 1;   end if;    select id as id_inner;end;set @id = 10; call pr_param_in(@id); select @id as id_out;mysql> call pr_param_in(@id);+----------+| id_inner |+----------+|       11 |+----------+ mysql> select @id as id_out;+--------+| id_out |+--------+| 10     |+--------+可以看到:用户变量 @id 传入值为 10,执行存储过程后,在过程内部值为:11(id_inner),但外部变量值依旧为:10(id_out)。

MySQL 存储过程 “out” 参数:从存储过程内部传值给调用者。在存储过程内部,该参数初始值为 null,无论调用者是否给存储过程参数设置值。

create procedure pr_param_out(   out id int)begin   select id as id_inner_1;    /* id 初始值为 null*/    if (id is not null) then          set id = id + 1;       select id as id_inner_2;   else      select 1 into id;   end if;    select id as id_inner_3;end;set @id = 10; call pr_param_out(@id); select @id as id_out;mysql> set @id = 10;mysql>mysql> call pr_param_out(@id);    /*外部变量不能传给存储过程*/+------------+| id_inner_1 |+------------+|       NULL |+------------+ +------------+| id_inner_3 |+------------+|          1 |+------------+ mysql> select @id as id_out;  /*过程将改变的值传给外部变量*/+--------+| id_out |+--------+| 1      |+--------+可以看出,虽然我们设置了用户定义变量 @id 为 10,传递 @id 给存储过程后,在存储过程内部,id 的初始值总是 null(id_inner_1)。最后 id 值(id_out = 1)传回给调用者。

MySQL 存储过程 inout 参数跟 out 类似,都可以从存储过程内部传值给调用者。不同的是:调用者还可以通过 inout 参数传递值给存储过程。

drop procedure if exists pr_param_inout; create procedure pr_param_inout(   inout id int)begin   select id as id_inner_1;  -- id 值为调用者传进来的值    if (id is not null) then      set id = id + 1;       select id as id_inner_2;   else      select 1 into id;   end if;    select id as id_inner_3;end;set @id = 10; call pr_param_inout(@id); select @id as id_out;mysql> set @id = 10; mysql>mysql> call pr_param_inout(@id);+------------+| id_inner_1 |+------------+|         10 |+------------+ +------------+| id_inner_2 |+------------+|         11 |+------------+ +------------+| id_inner_3 |+------------+|         11 |+------------+mysql>mysql> select @id as id_out;+--------+| id_out |+--------+| 11     |+--------+从结果可以看出:我们把 @id(10),传给存储过程后,存储过程最后又把计算结果值 11(id_inner_3)传回给调用者。 MySQL 存储过程 inout 参数的行为跟 C 语言函数中的引用传值类似。

通过以上例子:如果仅仅想把数据传给 MySQL 存储过程,那就使用“in” 类型参数;如果仅仅从 MySQL 存储过程返回值,那就使用“out” 类型参数;如果需要把数据传给 MySQL 存储过程,还要经过一些计算后再传回给我们,此时,要使用“inout” 类型参数。

9、声明和设置变量

(1) 声明变量

   在存储例程使用局部变量之前,必须声明局部变量,变量声明通过DECLARE语句实现,其原型如下:

   DECLARE variable_name TYPE ;

如:DECLARE x VARCHAR(254);

   在声明变量时,声明必须放在BEGIN/END块中。此外声明必须在执行该块任何其它语句之前进行。

(2) 设置变量

SET语句用来设置声明的存储例程变量值。其原型如下:

SET  variable_name =value;

如下声明和设置变量过程:

  DECLARE  x  INT;

SET  x = 155;

也可使用SELECT…..INTO语句设置变量。

  如:

SELECT  155  INTO  x;

当然,此变量是声明该变量的BEGIN/END块作用范围内的一个局部变量。如果希望在存储例程外使用此变量,需要将其作为OUT变量传递。

10、执行存储例程

    执行存储例程一般是通过CALL和SELECT语句来完成的。

    三、多语句存储例程

单语句存储例程非常有用,但存储例程的真正功能在于它能够封装和执行多个SQL语句。

下面介绍创建多语句存储例程时常用的语法。

  1、BEGIN和END

当创建多语句存储例程时,需要将语句包围在BEGIN/END块中。

此块的原型如下:

BEGIN

     statement 1;

     statement 2;

     ……

     statement N;

END

注意,块中每条语句必须以分号结尾。

 2、条件语句

˜ IF-ELSEIF-ELSE语句

 和C语言中if语句相似。

其原型如下:

IF condition1 THEN

statement1;

ELSEIF condition2 THEN

Statement2;

…….

END IF

˜ CASE语句

需要比较一组可能的值时CASE语句很有用。也是一种条件判断语句。

其原型如下:

CASE

WHEN condition1 THEN statement1;

WHEN condition2 THEN statement2;

………

END CASE;

3、迭代

有些任务需要能够重复地执行一组语句。下面介绍能够迭代执行和退出循环的各种方法。

˜ ITERATE语句

执行ITERATE语句将使嵌入该语句的LOOP、REPEAT或WHILE循环返回顶部,并在此执行。

其原型如下:

ITERATE  label

˜ LEAVE语句

在得到变量的值或特定任务的结果后,可能希望通过LEAVE命令立即退出循环或BEGIN/END块。

其原型如下:

LEAVE  label

˜ LOOP语句

LOOP语句将不断的迭代处理定义在其代码块中的一组语句,直到遇到LEAVE为止。

其原型如下:

[begin_label:]  LOOP

   Statement_list

END LOOP  [end_label]

      ˜ REPEAT语句

       REPEAT语句在操作上几乎与WHILE相同,很想C语言中的DO….WHERE语句。

      其原型如下:

 REPEAT

       Statement_list

 UNTIL condition

 END REPEAT

˜ WHILE语句

 其原型如下:

  WHILE condition DO

    Statement_list

        END WHILE

下面写一个循环语句的存储过程:

DELIMITER $$

 

DROP PROCEDURE IF EXISTS `yyw`.`p2` $$

CREATE PROCEDURE `yyw`.`p2` ()

BEGIN

        declare v int;

 set v=0;

 LOOP_LABLE:loop

          if v=3 then

      set v=v+1;

      ITERATE LOOP_LABLE;

   end if;

   insert into vs values(v);          /*将循环值插入数据表vs中*/

   set v=v+1;

   if v>=5 then

     leave LOOP_LABLE;

   end if;

 end loop;

END $$

 

DELIMITER ;

    四、从另一个例程中调用例程

DELIMITER //

CREATE PROCEDURE  p1()

BEGIN

   Statement_list

END//

CREATE PROCEDURE  p2()

BEGIN

   Statement_list

END//

CREATE PROCEDURE  p3()

BEGIN

   CALL  p1();

   CALL  p2();

END//

 

注意:直接采用MySQL的Administrator管理器编辑时,可以直接采用函数文本录入;
    但若在脚本中自动导入存储过程或函数时,由于MySQL默认以";"为分隔符,则过程体的每一句都被MySQL以存储过程编译,则编译过程会报错;所以要事先用DELIMITER关键字申明当前段分隔符
用完了就把分隔符还原。 如下所示:
DELIMITER $$
Stored Procedures and Functions
DELIMITER ;

    五、删除和查看存储例程

1、删除存储例程

要删除存储例程,可以执行DROP语句。

其原型如下:

 DROP  (PROCEDURE|FUNCTION)  P_name;

   2、查看例程状态

其原型如下:

SHOW  (PROCEDURE|FUNCTION)  STATUS  LIKE  ‘P_name’

如:

SHOW  PROCEDURE  STATUS  LIKE  ‘P3’/G;

注意: 使用/G选项以垂直格式显示输出信息。

   3、查看例程的创建语法

   通过SHOW CREATE语句可以查看创建特定例程所用的语法。

   其原型如下;

      SHOW CREATE  (PROCEDURE|FUNCTION)  Db_name.P_name

    六、实例

   一般在MySQL Query Browser中更方便的创建存储过程及修改内容。

(1)简单的加法运算

DELIMITER $$

 

DROP PROCEDURE IF EXISTS `yyw`.`p4` $$

CREATE DEFINER=`yang`@`10.10.19.161` PROCEDURE `p4`(a int,b int)

BEGIN

   declare c int;             /*声明的变量

if a is null then            /*IF语句  

      set a = 0;

   end if;

if b is null then

      set b = 0;

   end if;

set c = a + b;

select c as sum;          /*结果显示c的值

 

END $$

 

DELIMITER ;

调用以下:CALL  p4(3,4);

将显示:

+------+

| sum  |

+------+

|    7 |

+------+

1 row in set (0.00 sec)

(2)存储过程中的循环语句、数据表数据的导入导出及SQL函数的使用

DELIMITER $$

 

DROP PROCEDURE IF EXISTS `yyw`.`p4` $$

CREATE DEFINER=`yang`@`10.10.19.161` PROCEDURE ‘pro_prime2’(in num int)

BEGIN

  declare i,j,x,y int default 0;    /*声明变量并默认为0*/
      select  yywID into j from text1;  /*从数据表txte1中字段yywID的值赋给变量j*/
      select 'count ',j;           /*显示count字符和j的值*/
      while i         set x=2;
         pp1:while x            if j%x=0 then               /*if循环语句*/
               set y=1;
               leave pp1;
            else
               set x=x+1;
            end if;
         end while;
         if y=1 then
           set y=0;
         else
           set i=i+1;
           insert into text2 values(j);    /*将j的值插入数据表text2*/
         end if;
           set j=j+1;            /*实现j的自增*/
      end while;
 END $$

 

DELIMITER ;

假如原先在数据库中分别建立表text1和text2,text1中有一个字段初始值为3,text2为空;

下面执行一下此存储过程:

mysql> CALL pro_prime2(5);

+--------+------+

| count  | j    |

+--------+------+

| count  |    3 |

+--------+------+

1 row in set (0.00 sec)

mysql> select *from text2;

+-------+

| yywID |

+-------+

|     3 |

|     5 |

|     7 |

|    11 |

|    13 |

+-------+

5 rows in set (0.00 sec)

 

(3)用存储过程实现计算数据库中某个成绩表总分及平均分,并且调用过程后

能够自动显示基本信息(如学号、姓名、总分、平均分等)。

    首先在数据库中建一个成绩表(命名为chengjibiao)如下:

+-----+------+--------+-------+--------+
| NUM | Name | Enlish | Maths | Physis |
+-----+------+--------+-------+--------+
|   1 | 杨业 | 92     | 87    | 96     |
|   2 | 剑锋 | 82     | 98    | 93     |
|   3 | 张美 | 96     | 86    | 94     |
|   4 | 张文 | 76     | 99    | 95     |
|   5 | 叶倩 | 97     | 86    | 88     |
|   6 | 方文 | 87     | 96    | 94     |
|   7 | 李丽 | 97     | 86    | 83     |
|   8 | 贾宇 | 67     | 89    | 77     |
|   9 | 王勃 | 89     | 67    | 75     |
|  10 | 刘三 | 85     | 78    | 95     |
+-----+------+--------+-------+--------+

 

 ‚ 用SQL语句写存储过程p1    

                 DELIMITER $$

                                                

                DROP PROCEDURE IF EXISTS `yyw`.`p1` $$

                CREATE DEFINER=`yang`@`10.10.19.161` PROCEDURE `p1`(N int)

                BEGIN

                declare a int;                  /*    变量的声明   */

                declare b int;

                declare c int;

                declare d int;

                declare e int;

                declare f char(100);

                declare g decimal(4,2);

                set e=1;

                create table zongping (NUM int,Name char(255),Enlish int,Maths int,Physis int,Total int,aver decimal(        4,2));                     /*  建一个数据表以存放要显示的内容*/

                repeat                 /* 引进一个REPEAT循环,来计算每位学生总分及平均分*/

                select  Enlish,Maths,Physis,Name into a,b,c,f from chengjibiao where NUM=e;

                       /* 导出数据库chengjibiao中的三门成绩及姓名,并把它们分别赋给变量a,b,c,f;*/

                set d=a+b+c;         /*求和*/

                set g=(a+b+c)/3;      /*求平均分*/

                insert into zongping (NUM,Name,Enlish,Maths,Physis,Total,aver) values (e,f,a,b,c,d,g);

                 /*将学号,姓名,三门成绩,总分,平均分的数据插入新建的数据表zongping中

                set e=e+1;       /*该条件可结束循环*/

                until e=N      /*N是调用存储过程时根据学生数目来设定的*/

                end repeat;

                select *from zongping;           /* 以数据表的形式显示运行结果*/

               drop table zongping;          /*显示结果后删除表,也可不删*/

               END $$

                                  

               DELIMITER ;

                             

  l 调用存储过程

               CALL  P1 (11);          /* 因为原成绩表中有10列数据 ,故设N=11,也可根据不同的成绩表另设

                            

       显示结果如下:

   +------+------+--------+-------+--------+-------+

 | Name | Enlish | Maths | Physis | Total | Aver  |
+------+------+--------+-------+--------+-------+-------+
|    1 | 杨业 |     92 |    87 |     96 |   275 | 91.67 |
|    2 | 剑锋 |     82 |    98 |     93 |   273 | 91.00 |
|    3 | 张美 |     96 |    86 |     94 |   276 | 92.00 |
|    4 | 姜文 |     76 |    99 |     95 |   270 | 90.00 |
|    5 | 叶倩 |     97 |    86 |     88 |   271 | 90.33 |
|    6 | 方文 |     87 |    96 |     94 |   277 | 92.33 |
|    7 | 李丽 |     97 |    86 |     83 |   266 | 88.67 |
|    8 | 贾宇 |     67 |    89 |     77 |   233 | 77.67 |
|    9 | 王勃 |     89 |    67 |     75 |   231 | 77.00 |
|   10 | 刘三 |     85 |    78 |     95 |   258 | 86.00 |
+------+------+--------+-------+--------+-------+-------+

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to use Xiaohongshu account to find users? Can I find my mobile phone number? How to use Xiaohongshu account to find users? Can I find my mobile phone number? Mar 22, 2024 am 08:40 AM

With the rapid development of social media, Xiaohongshu has become one of the most popular social platforms. Users can create a Xiaohongshu account to show their personal identity and communicate and interact with other users. If you need to find a user’s Xiaohongshu number, you can follow these simple steps. 1. How to use Xiaohongshu account to find users? 1. Open the Xiaohongshu APP, click the "Discover" button in the lower right corner, and then select the "Notes" option. 2. In the note list, find the note posted by the user you want to find. Click to enter the note details page. 3. On the note details page, click the "Follow" button below the user's avatar to enter the user's personal homepage. 4. In the upper right corner of the user's personal homepage, click the three-dot button and select "Personal Information"

Local users and groups are missing on Windows 11: How to add it Local users and groups are missing on Windows 11: How to add it Sep 22, 2023 am 08:41 AM

The Local Users and Groups utility is built into Computer Management and can be accessed from the console or independently. However, some users find that local users and groups are missing in Windows 11. For some people who have access to it, the message suggests that this snap-in may not work with this version of Windows 10. To manage user accounts for this computer, use the User Accounts tool in Control Panel. The issue has been reported in previous iterations of Windows 10 and is usually caused by issues or oversights on the user's side. Why are local users and groups missing in Windows 11? You are running Windows Home edition, local users and groups are available on Professional edition and above. Activity

Log in to Ubuntu as superuser Log in to Ubuntu as superuser Mar 20, 2024 am 10:55 AM

In Ubuntu systems, the root user is usually disabled. To activate the root user, you can use the passwd command to set a password and then use the su- command to log in as root. The root user is a user with unrestricted system administrative rights. He has permissions to access and modify files, user management, software installation and removal, and system configuration changes. There are obvious differences between the root user and ordinary users. The root user has the highest authority and broader control rights in the system. The root user can execute important system commands and edit system files, which ordinary users cannot do. In this guide, I'll explore the Ubuntu root user, how to log in as root, and how it differs from a normal user. Notice

Explore Windows 11 guide: How to access user folders on your old hard drive Explore Windows 11 guide: How to access user folders on your old hard drive Sep 27, 2023 am 10:17 AM

Certain folders are not always accessible due to permissions, and in today’s guide we will show you how to access user folders on your old hard drive on Windows 11. The process is simple but can take a while, sometimes even hours, depending on the size of the drive, so be extra patient and follow the instructions in this guide closely. Why can't I access my user folders on my old hard drive? User folders are owned by another computer, so you cannot modify them. You don't have any permissions on the folder other than ownership. How to open user files on old hard drive? 1. Take ownership of the folder and change permissions Find the old user directory, right-click on it and select Properties. Navigate to "An

Tutorial: How to delete a normal user account in Ubuntu system? Tutorial: How to delete a normal user account in Ubuntu system? Jan 02, 2024 pm 12:34 PM

Many users have been added to the Ubuntu system. I want to delete the users that are no longer in use. How to delete them? Let’s take a look at the detailed tutorial below. 1. Open the terminal command line and use the userdel command to delete the specified user. Be sure to add the sudo permission command, as shown in the figure below. 2. When deleting, be sure to be in the administrator directory. Ordinary users do not have this permission. , as shown in the figure below 3. After the delete command is executed, how to judge whether it has been truly deleted? Next we use the cat command to open the passwd file, as shown in the figure below 4. We see that the deleted user information is no longer in the passwd file, which proves that the user has been deleted, as shown in the figure below 5. Then we enter the home file

What is sudo and why is it important? What is sudo and why is it important? Feb 21, 2024 pm 07:01 PM

sudo (superuser execution) is a key command in Linux and Unix systems that allows ordinary users to run specific commands with root privileges. The function of sudo is mainly reflected in the following aspects: Providing permission control: sudo achieves strict control over system resources and sensitive operations by authorizing users to temporarily obtain superuser permissions. Ordinary users can only obtain temporary privileges through sudo when needed, and do not need to log in as superuser all the time. Improved security: By using sudo, you can avoid using the root account during routine operations. Using the root account for all operations may lead to unexpected system damage, as any mistaken or careless operation will have full permissions. and

Windows 11 KB5031455 fails to install, causing other issues for some users Windows 11 KB5031455 fails to install, causing other issues for some users Nov 01, 2023 am 08:17 AM

Microsoft began rolling out KB2 to the public as an optional update for Windows 503145511H22 or later. This is the first update to enable Windows 11 Moment 4 features by default, including Windows Copilot in supported areas, preview support for items in the Start menu, ungrouping of the taskbar, and more. Additionally, it fixes several Windows 11 bugs, including potential performance issues that caused memory leaks. But ironically, the optional update for September 2023 will be a disaster for users trying to install the update, or even for those who have already installed it. Many users will not install this Wi

Huawei will launch innovative MED storage products next year: rack capacity exceeds 10 PB and power consumption is less than 2 kW Huawei will launch innovative MED storage products next year: rack capacity exceeds 10 PB and power consumption is less than 2 kW Mar 07, 2024 pm 10:43 PM

This website reported on March 7 that Dr. Zhou Yuefeng, President of Huawei's Data Storage Product Line, recently attended the MWC2024 conference and specifically demonstrated the new generation OceanStorArctic magnetoelectric storage solution designed for warm data (WarmData) and cold data (ColdData). Zhou Yuefeng, President of Huawei's data storage product line, released a series of innovative solutions. Image source: Huawei's official press release attached to this site is as follows: The cost of this solution is 20% lower than that of magnetic tape, and its power consumption is 90% lower than that of hard disks. According to foreign technology media blocksandfiles, a Huawei spokesperson also revealed information about the magnetoelectric storage solution: Huawei's magnetoelectronic disk (MED) is a major innovation in magnetic storage media. First generation ME

See all articles