MySQL存储过程与自定义函数

一、存储过程

  1、定义:一组为了完成特定功能的SQL语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来调用存储过程

  2、好处:

     (1) 重复使用。存储过程可以重复使用,从而可以减少数据库开发人员的工作量。

          (2) 提高性能。存储过程在创建的时候就进行了编译,将来使用的时候不用再重新编译。一般的SQL语句每执行一次就需要编译一次,所以使用存储过程提高了效率。

            (3) 减少网络流量。存储过程位于服务器上,调用的时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输的数据量。

            (4 )安全性。参数化的存储过程可以防止SQL注入式的攻击,而且可以将Grant、Deny以及Revoke权限应用于存储过程

  3、创建语法 

CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
   存储过程体(一组合法的SQL语句)
END

    注意点:

      1)参数列表包含三部分:参数模式  参数名  参数类型,举例:in stuname varchar(20)

      2)参数模式:

      in:该参数可以作为输入,也就是该参数需要调用方传入值

      out:该参数可以作为输出,也就是该参数可以作为返回值

      inout:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值

       3)如果存储过程体仅仅只有一句话,begin end可以省略,存储过程体中的每条sql语句的结尾要求必须加分号。

       4)存储过程的结尾可以使用 delimiter 重新设置。语法:delimiter 结束标记,案例:delimiter $

  4、调用语法:CALL 存储过程名(实参列表);

    1)空参列表

#案例1:插入到admin表中五条记录
DELIMITER $ CREATE PROCEDURE myp1() BEGIN INSERT INTO admin(username,`password`) VALUES(
'john1','0000'),('lily','0000'),('rose','0000'),('jack','0000'),('tom','0000'); END $ #调用 CALL myp1()$

    2)创建带in模式参数的存储过程

#案例2:创建存储过程实现,用户是否登录成功
CREATE PROCEDURE myp4(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
    DECLARE result INT DEFAULT 0;#声明并初始化
    
    SELECT COUNT(*) INTO result#赋值
    FROM admin
    WHERE admin.username = username
    AND admin.password = PASSWORD;
    
    SELECT IF(result>0,'成功','失败');#使用
END $

#调用
CALL myp3('张飞','8888')$

   3)创建out 模式参数的存储过程

#案例3:根据输入的女神名,返回对应的男神名和魅力值
CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT) 
BEGIN
    SELECT boys.boyname ,boys.usercp INTO boyname,usercp
    FROM boys 
    RIGHT JOIN
    beauty b ON b.boyfriend_id = boys.id
    WHERE b.name=beautyName ;
END $

#调用
CALL myp7('小昭',@name,@cp)$
SELECT @name,@cp$

  4)创建带inout模式参数的存储过程

#案例4:传入a和b两个值,最终a和b都翻倍并返回

CREATE PROCEDURE myp8(INOUT a INT ,INOUT b INT)
BEGIN
    SET a=a*2;
    SET b=b*2;
END $

#调用
SET @m=10$
SET @n=20$
CALL myp8(@m,@n)$
SELECT @m,@n$

  5、删除存储过程

    #语法:drop procedure 存储过程名

         DROP PROCEDURE p1;

         DROP PROCEDURE p2,p3;#×   同时只能删除一个存储过程

  6、查看存储过程的信息

    DESC myp2;×

    SHOW CREATE PROCEDURE  存储过程名称;

  7、案例讲解

 1 #一、创建存储过程实现传入用户名和密码,插入到admin表中
 2 
 3 CREATE PROCEDURE test_pro1(IN username VARCHAR(20),IN loginPwd VARCHAR(20))
 4 BEGIN
 5     INSERT INTO admin(admin.username,PASSWORD)
 6     VALUES(username,loginpwd);
 7 END $
 8 
 9 #二、创建存储过程实现传入女神编号,返回女神名称和女神电话
10 
11 CREATE PROCEDURE test_pro2(IN id INT,OUT NAME VARCHAR(20),OUT phone VARCHAR(20))
12 
13 BEGIN
14     SELECT b.name ,b.phone INTO NAME,phone
15     FROM beauty b
16     WHERE b.id = id;
17 
18 END $
19 #三、创建存储存储过程或函数实现传入两个女神生日,返回大小
20 
21 CREATE PROCEDURE test_pro3(IN birth1 DATETIME,IN birth2 DATETIME,OUT result INT)
22 BEGIN
23     SELECT DATEDIFF(birth1,birth2) INTO result;
24 END $
25 #四、创建存储过程或函数实现传入一个日期,格式化成xx年xx月xx日并返回
26 CREATE PROCEDURE test_pro4(IN mydate DATETIME,OUT strDate VARCHAR(50))
27 BEGIN
28     SELECT DATE_FORMAT(mydate,'%y年%m月%d日') INTO strDate;
29 END $
30 
31 CALL test_pro4(NOW(),@str)$
32 SELECT @str $
33 
34 #五、创建存储过程或函数实现传入女神名称,返回:女神 and 男神  格式的字符串
35 如 传入 :小昭
36 返回: 小昭 AND 张无忌
37 DROP PROCEDURE test_pro5 $
38 CREATE PROCEDURE test_pro5(IN beautyName VARCHAR(20),OUT str VARCHAR(50))
39 BEGIN
40     SELECT CONCAT(beautyName,' and ',IFNULL(boyName,'null')) INTO str
41     FROM boys bo
42     RIGHT JOIN beauty b ON b.boyfriend_id = bo.id
43     WHERE b.name=beautyName;
44 END $
45 
46 CALL test_pro5('柳岩',@str)$
47 SELECT @str $
48 
49 #六、创建存储过程或函数,根据传入的条目数和起始索引,查询beauty表的记录
50 DROP PROCEDURE test_pro6$
51 CREATE PROCEDURE test_pro6(IN startIndex INT,IN size INT)
52 BEGIN
53     SELECT * FROM beauty LIMIT startIndex,size;
54 END $
55 
56 CALL test_pro6(3,5)$
View Code

 二、自定义函数

  1、定义:自定义函数是一种与存储过程十分相似的过程式数据库对象。它与存储过程一样,都是由SQL语句和过程式语句组成的代码片段,并且可以被应用程序和其他SQL语句调用。

   2、自定义函数与存储过程的区别:

   1)自定义函数不能拥有输出参数,这是因为自定义函数自身就是输出参数;而存储过程可以拥有输出参数。

     2)自定义函数中必须包含一条 RETURN 语句,而这条特殊的 SQL 语句不允许包含于存储过程中。

     3)可以直接对自定义函数进行调用而不需要使用 CALL 语句,而对存储过程的调用需要使用 CALL 语句。

     4)函数只会返回一个值,不允许返回一个结果集。函数强调返回值,所以函数不允许返回多个值的情况,即使是查询语句。

  关键字 调用语法 返回值 应用场景
函数 FUNCTION SELECT 函数() 只能是一个 一般用于查询结果为一个值并返回时,当有返回值而且仅仅一个
存储过程 PROCEDURE CALL 存储过程() 可以有0个或多个 一般用于更新

  3、创建语法

CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
BEGIN
    函数体
END

  注意点:

   1)参数列表 包含两部分:参数名 参数类型

   2)函数体:肯定会有return语句,如果没有会报错;如果return语句没有放在函数体的最后也不报错,但不建议;return 值;

   3)函数体中仅有一句话,则可以省略begin end

   4)使用 delimiter语句设置结束标记

 4、调用语法

  1)无参有返回

#案例1:返回公司的员工个数
CREATE FUNCTION myf1() RETURNS INT
BEGIN
    DECLARE c INT DEFAULT 0;#定义局部变量
    SELECT COUNT(*) INTO c#赋值
    FROM employees;
    RETURN c;
END $

SELECT myf1()$

  2)有参有返回

#案例2:根据员工名,返回它的工资
CREATE FUNCTION myf2(empName VARCHAR(20)) RETURNS DOUBLE
BEGIN
    SET @sal=0;#定义用户变量 
    SELECT salary INTO @sal   #赋值
    FROM employees
    WHERE last_name = empName;
    RETURN @sal;
END $

SELECT myf2('k_ing') $
#案例3:根据部门名,返回该部门的平均工资
CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE
BEGIN
    DECLARE sal DOUBLE ;
    SELECT AVG(salary) INTO sal
    FROM employees e
    JOIN departments d ON e.department_id = d.department_id
    WHERE d.department_name=deptName;
    RETURN sal;
END $

SELECT myf3('IT')$

  5、查看函数

   SHOW CREATE FUNCTION myf3;

  6、删除函数

   DROP FUNCTION myf3;

  7、案例

#一、创建函数,实现传入两个float,返回二者之和
CREATE FUNCTION test_fun1(num1 FLOAT,num2 FLOAT) RETURNS FLOAT
BEGIN
    DECLARE SUM FLOAT DEFAULT 0;
    SET SUM=num1+num2;
    RETURN SUM;
END $

SELECT test_fun1(1,2)$
原文地址:https://www.cnblogs.com/zhufeng123/p/13904832.html