• 04-存储过程&函数


    存储过程

    概述

    过程化 SQL 块主要有 2 种类型,即命名块和匿名块。前面介绍的是匿名块。匿名块每次执行时都要进行编译,它不能被存储到 DB 中,也不能在其他过程化 SQL 块中调用。过程和函数是命名块,它们被编译后保存在 DB 中,称为“持久性存储模块”,可以被反复调用,运行速度较快。

    存储过程是由过程化 SQL 语句书写的过程,这个过程经过编译和优化后存储在 DB 服务器中,因此称它为“存储过程”,使用时只要调用即可。

    定义

    CREATE OR REPLACE PROCEDURE <存储过程名>([参数1, 参数2, ...]) /* 存储过程首部 */
    BEGIN
        /* 存储过程体, 描述该存储过程的操作, 是一组 SQL 语句 */
    END
    
    • 存储过程包括过程首部和过程体
    • 在过程首部,“过程名”是 DB 服务器合法的对象标识
    • 参数列表包含 3 部分:参数模式 参数名 参数类型
      • 举例:IN stuName VARCHAR(20)
      • IN 该参数可作为输入,调用方需要传入值到该参数中
      • OUT 可作为输出,也就是过程返回值
      • INOUT 既可以作为输入,又可以作为输出
    • 过程体 // 如果只有一句话,BEGIN...END 可省
      • 存储过程体中的每条 SQL 语句的结尾要求必须加 ;
      • 存储过程的结尾可以使用 DELIMITER 重新设置

    操作

    1. 执行存储过程:CALL <过程名>(实参列表);
    2. 删除存储过程:DROP PROCEDURE <过程名>;
    3. 查看存储过程:SHOW CREATE PROCEDURE <过程名>;

    案例

    1. [无参] 插入到 admin 表中 5 条记录
    2. [带 IN 模式] 创建过程实现根据 beauty.name 查询对应的 boy 信息
      CREATE PROCEDURE myPro2(IN beautyName VARCHAR(20))
      BEGIN
          SELECT bo.*
          FROM boys bo
          RIGHT JOIN beauty b ON bo.id = b.boyfriend_id
          WHERE b.name = beautyName;
      END $
      
    3. [带 IN 模式] 创建过程实现用户是否登录成功
      CREATE PROCEDURE myPro3(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 $
      
    4. [带 OUT 模式] 根据 beauty.name,返回对应的 boy.boyName
    5. [带 OUT 模式] 根据 beauty.name,返回对应的 boy.id 和 boy.boyName
      CREATE PROCEDURE myPro5(IN bName VARCHAR(20), OUT id VARCHAR(20), OUT name VARCHAR(20))
      BEGIN
          SELECT bo.id, bo.boyName INTO id, name
          FROM boys bo
          INNER JOIN beauty b ON bo.id = b.boyfriend_id
          WHERE b.name = bName;
      END $
      
    6. [带 INOUT 模式] 传入 a 和 b 两个变量,调用过程后,a 和 b 的值翻倍
    7. 创建过程实现传入一个日期,格式化成:xx 年 xx 月 xx 日并返回
      CREATE PROCEDURE myPro7(IN myDate DATETIME, OUT dateStr VARCHAR(30))
      BEGIN
          SELECT DATE_FORMAT(myDate, '%y 年 %m 月 %d 日') INTO strDate;
      END $
      
    8. 创建过程实现传入 beauty.name,返回:'beauty.name and boys.name' 格式的字符串
      CREATE PROCEDURE myPro8(IN beautyName VARCHAR(20), OUT result VARCHAR(20))
      BEGIN
          SELECT CONCAT(beautyName, ' and ', IFNULL(boyName, 'NULL')) INTO result
          FROM boys bo
          RIGHT JOIN beauty b ON bo.id = b.boyfriend_id
          WHERE b.name = beautyName;
      END $
      
    9. 创建过程实现根据传入的条目数和起始索引,查询 beauty 表的记录
      CREATE PROCEDURE myPro8(IN startIndex INT, IN size INT)
      BEGIN
          SELECT * FROM beauty LIMIT startIndex, size;
      END $
      

    函数

    函数也称为”自定义函数“,因为是用户自己使用过程化 SQL 设计定义的。函数和存储过程类似,都是持久性存储模块。函数的定义和存储过程也类似,不同之处是函数必须指定返回的类型。

    • 存储过程:可以有 0 个返回,也可以有多个返回,适合做批量插入,批量更新
    • 函数:有且只有 1 个返回,适合做处理数据后返回一个结果

    定义

    CREATE FUNCTION <函数名>([参数名 参数类型 ...]) RETURNS <类型>
    BEGIN
        /* 函数体 */
        return 值;
    END $
    

    操作

    1. 调用函数:SELECT 函数名(参数列表)
    2. 删除函数:DROP FUNCTION <函数名>
    3. 查看函数:SHOW CREATE FUNCTION <函数名>

    案例

    1. [无参有返回值] 返回 beauty 表记录数
    2. [有参有返回] 根据员工名,返回他的工资
      CREATE FUNCTION func2(empName VARCHAR(20)) RETURNS DOUBLE
      BEGIN
          SET @sal=0; # 定义用户变量
          SELECT salary INTO @sal
          FROM employees WHERE last_name = empName;
          RETURN @sal;
      END $
      
    3. 根据部门名返回该部门的平均工资
      CREATE FUNCTION func3(deptName VARCHAR(20)) RETURNS DOUBLE
      BEGIN
          DECLARE avgSal DOUBLE;
          SELECT AVG(salary) INTO avgSal
          FROM employees e RIGHT JOIN departments d
          ON e.department_id = d.department_id
          WHERE d.department_name = deptName;
          RETURN avgSal;
      END $
      
    4. 创建函数,传入两个 float,返回二者之和
      CREATE FUNCTION func4(num1 FLOAT, num2 FLOAT) RETURNS FLOAT
      BEGIN
          DECLARE sum FLOAT DEFAULT 0;
          SET sum = num1 + num2;
          RETURN sum;
      END $
      
  • 相关阅读:
    [ lucene高级 ] lucene中的算法PriorityQueue
    [ lucene扩展 ] MoreLikeThis 相似检索
    排序08归并排序
    lucene中的数值型字段(NumericField)
    两三年前的搜索管理系统
    java中的集合包简要分析
    倒排索引基础
    散列02java中的hashMap
    Mysql数据库中InnoDB和MyISAM的差别
    ajax 乱码
  • 原文地址:https://www.cnblogs.com/liujiaqi1101/p/13622823.html
Copyright © 2020-2023  润新知