• 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)$
  • 相关阅读:
    hi35183e增加exfat文件系统的支持(转)
    UDP 单播、广播和多播(转)
    linux系统中,kill -3查看java进程状态无效的解决方法
    js是用什么语言编写实现的
    云海天教程
    Docker下安装MySQL
    如何延长手机的使用寿命时间
    如何延长空调使用寿命?
    Linux 发送邮件
    Linux jstack命令
  • 原文地址:https://www.cnblogs.com/zhufeng123/p/13904832.html
Copyright © 2020-2023  润新知