【Mysql 存储过程 Or 存储函数 傻傻分不清?

2023年 9月 9日 79.4k 0

  MySQL的存储函数(自定义函数)和存储过程都是用于存储SQL语句的。但是什么时候用什么呢?是不是总是傻傻的分不清?
本文来详细的讲一下存储函数 和存储过程 ,以后再也不会迷糊。

一、 异同点

MySQL的存储过程和函数都是一系列SQL语句的集合,调用时一次性执行这些SQL语句。但是它们有一些不同之处:

  • 存储过程没有返回值,而函数有一个返回值.
  • 存储过程可以在单个存储过程中执行一系列SQL语句,而自定义函数有诸多限制.
  • 存储过程可以返回多个值,而函数只能有一个返回值.
  • 存储过程实现较为复杂,自定义函数针对性强
  • 存储函数只能有输入参数,而且不能带in, 而存储过程可以有多个in,out,inout参数。
  • 存储过程可以调用存储函数、但函数不能调用存储过程。
  • 名称 创建 调用 返回 应用
    存储函数 create function select 只能是一个 计算字段值、处理数据、触发器(一般用于查询结果为一个值并有返回结果的)
    存储过程 create procedure call 可以是多个也可以为空 1.复杂的业务逻辑,例如银行转账、订单处理;2.批量操作,例如批量插入、更新、删除数据;3.安全性控制,例如限制用户访问某些数据或执行某些操作(一般用于更新)

    二、 存储函数

    存储函数(自定义函数)是一种对MySQL扩展的途径,其用法与内置的函数相同。

    语法

    创建

    CREATE FUNCTION 函数名([func_parameter[...]])

    RETURNS type

    [characteristic ...]

    BEGIN

    函数体

    -- sql语句

    END

    函数名:表示存储函数的名称;

    func_parameter:表示存储函数的参数列表,指定参数为IN、OUT或INOUT只对PROCEDURE是合法的,FUNCTION中总是默认为IN参数。

    RETURNS type:语句表示函数返回数据的类型;

    characteristic:创建函数时指定的对函数的约束。

    func_parameter :由参数名称和参数类型组成。

    函数体:函数主体,包含函数逻辑和SQL语句.

    示例:

    delimiter $$
    CREATE FUNCTION avg_salary(p_name VARCHAR(50))
    
    RETURNS FLOAT
    
    BEGIN
    
        DECLARE avg_age FLOAT;
    
        DECLARE total_salary FLOAT;
    
        DECLARE num_employees INT;
    
        DECLARE cur CURSOR FOR SELECT age FROM employees WHERE name = p_name;
    
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET num_employees = 0;
    
        OPEN cur;
    
        FETCH cur INTO avg_age;
    
        CLOSE cur;
    
    
    
        SELECT AVG(salary) INTO total_salary FROM employees WHERE name = p_name;
    
    
    
        RETURN total_salary / avg_age;
    
    end $$
    
    delimiter ;
    

      上述示例存储函数接受一个参数p_name,表示要查询的员工姓名。它首先声明了三个变量:avg_age、total_salary和num_employees。然后,它使用游标遍历employees表中与指定名称匹配的所有行,并计算这些行中的平均年龄。最后,它返回总薪水除以平均年龄的结果。

    > delimiter 是分隔符的意思 DELIMITER xx
    > -- 示例:
    >  DELIMITER $$   -- 指定 $$ 为分隔符
    >  DELIMITER //   -- 指定 // 为分隔符 
    >  DELIMITER ;    -- 指定 ; 为分隔符
    

    调用

    SELECT func_name()

    调用函数名。

    查看

    查看定义: show create function func_name;
    查看状态:show function status like 'func_name';

    修改

    ALTER FUNCTION function_name(parameters) [characteristic ...];

    删除

    DROP FUNCTION func_name

      删除函数的语法只需写上函数名即可,函数的参数可以不用写出来。

    三、 存储过程

      存储过程是一组为了完成特定功能的SQL语句集合,经编译后存储在服务器端的数据库中,利用存储过程可以加速SQL语句的执行
    存储过程的优点是可以提高运行效率,且使用存储过程的系统更加稳定。
    存储过程的缺点是维护性较差,相对于简单SQL,存储过程的编写和调试都比较困难。

    语法

    创建
    存储过程的创建步骤需要以下几步:

  • 声明存储过程的名称和参数列表。
  • 编写存储过程的主体部分,包括一系列SQL语句。
  • 结束存储过程的主体部分,并指定返回值类型。
  • 调用存储过程,传递参数并获取返回结果。
  • create procedure 存储过程名 ([params])

    BEGIN

    存储过程体(一组合法的SQL语句)

    END

    参数列表(params):如果有多个参数则用逗号 , 分隔开,一个参数包括三部分:参数模式、参数名、参数类型,如:in name varchar(20)。参数模式有:in 输入、out 输出、inout 输入输出参数。

    关于IN | OUT | INOUT的详情如下:

    IN :表示输入参数;它必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值。仅需要将数据传入存储过程,并不需要返回计算后的该值。只能当做传入参数

    OUT: 表示输出参数;该值可在存储过程内部被改变,并可返回。不接受外部传入的数据,仅返回计算之后的值。只能当做转出参数。也就是说,即使传值给 OUT 参数,该参数也无法得到你传的值,得到的会是一个 null 值。

    INOUT 表示既可以输入也可以输出;该参数即可作为输入,又可做为输出,也就是该参数既需要传入值,又可以返回值。可当做传入转出参数

    示例:

    CREATE PROCEDURE GetEmployeeDetails(IN employeeID INT)
    
    BEGIN
    
        SELECT * FROM employees WHERE ID = employeeID;
    
    END;
    
    
    

      上述示例为一个名为GetEmployeeDetails的存储过程,接受一个整型参数employeeID,用于查询员工详情。在存储过程中,使用SELECT语句从employees表中查询employeeID对应的记录。最后,通过END关键字结束存储过程的主体部分。

    调用

    使用 call 关键字来调用存储过程

    call func_name([ proc_parameter [,proc_parameter ...]])

    当无参数时,可以省略括号,不写;

    当有参数时,不可省略括号。

    查看

    查看定义: show create procedurefunc_name;
    查看状态:show procedurestatus like 'func_name';

    修改

    alter procedure sp_name [characteristic ...]

    删除

    drop procedure sp_name;

    其中characteristic的取值为:

    说明
    language sql 说明routine_body部分是由SQL语句组成的,当前系统支持的语言为SQL
    [not] deterministic 指明存储过程执行的结果是否确定。DETERMINISTIC 表示结果是确定的。每次执行存储过程时,相同的输入会得到相同的输出。
    {contains sql / no sql / reads sql data / modifies sql data} 指明子程序使用SQL语句的限制。CONTAINS SQL表明子程序包含SQL语句,但是不包含读写数据的语句;NO SQL表明子程序不包含SQL语句;READS SQL DATA:说明子程序包含读数据的语句;MODIFIES SQL DATA表明子程序包含写数据的语句。默认情况下,系统会指定为CONTAINS SQL。
    sql_security{definer/invoker} 指明谁有权限来执行。DEFINER 表示只有定义者才能执行;INVOKER 表示拥有权限的调用者可以执行。默认情况下,系统指定为DEFINER。
    comment ‘string’ 注释信息,可以用来描述存储过程或函数

    在这里插入图片描述

      如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏  🙌一起讨论
      你的评价就是我✍️创作的动力!					  💞💞💞
    

    相关文章

    Oracle如何使用授予和撤销权限的语法和示例
    Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
    下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
    社区版oceanbase安装
    Oracle 导出CSV工具-sqluldr2
    ETL数据集成丨快速将MySQL数据迁移至Doris数据库

    发布评论