MySQL-存储过程和自定义函数

news2025/3/17 12:05:22

存储过程

        存储过程,一组预编译的 SQL 语句和流程控制语句,被命名并存储在数据库中。存储过程可以用来封装复杂的数据库操作逻辑,并在需要时进行调用。

使用存储过程

创建存储过程

create procedure 存储过程名()
begin
    存储过程的逻辑代码(可以包含 SQL 语句、控制结构和变量操作等)
end;

执行存储过程

call 存储过程名();

删除存储过程

drop procedure [if exists] 存储过程名;

使用参数

create procedure 存储过程名(
[in|out|inout] 参数名1参数的数据类型,
[in|out|inout] 参数名2 参数的数据类型,
)
begin
    存储过程的逻辑代码(可以包含 SQL 语句、控制结构和变量操作等)
end;

参数类型:

  • in(默认):输入参数(只读),存储过程的输入值,从外部传递给存储过程,存储过程内部是只读的,不能修改它的值
  • out:输出参数(只写),存储过程的返回值,存储过程可以修改它的值并将其返回
  • inout:输入和输出参数(可读可写)既可以作为输入值传递给存储过程,也可以由存储过程修改并返回

使用变量

在外部定义变量

set @varName
# 传入参数(只读)
create procedure mypro1(in i int)
begin
  select i;
  set i=2;
  select i;
end;

# 在外部定义变量
set @var=1;

call mypro1(@var);
select @var;
# 结果:1 2 1
# 传出参数(只写)
create procedure mypro2(out i int)
begin
  select i;
  set i=2;
  select i;
end;

# 在外部定义变量
set @var=1;

call mypro2(@var);
select @var;
# 结果:null null 2
# 传入传出参数(可读可写)
create procedure mypro3(inout i int)
begin
  select i;
  set i=2;
  select i;
end;

# 在外部定义变量
set @var=1;

call mypro3(@var);
select @var;
# 结果:1 2 2

在内部定义变量

declare 变量名 变量的数据类型[default 默认值];
create procedure mypro(in i int)
begin
  declare a double(7,2) default 1;  #初始化变量
  set i=2;
  select sal into a from emp limit 1;  #将字段赋值给变量
  select a;
end;

set @var=1;

call mypro(@var);
select @var;

    逻辑语句

    条件语句(if、case)

    if 条件 then
        逻辑代码;
    [elseif 条件 then
        逻辑代码;]
    [else
        逻辑代码;]
    end if;
    case
        when 条件1 then
            逻辑代码
        when 条件2 then
            逻辑代码
        else
            逻辑代码
    end case;

    循环语句(while、repeat)

    while 循环条件 do
        逻辑代码
    end while;
    repeat
        逻辑代码
    until 循环条件 end repeat;

    特点

    优点:

    • 代码复用:存储过程可以被多个应用程序或脚本调用,实现了代码的复用
    • 提高性能:MySQL 将编译后的存储过程放入缓存中。如果应用程序在单个连接中多次使用存储过程,直接使用编译版本
    • 减少网络流量:存储过程可以一次执行多条 SQL 语句,减少了与数据库的交互次数
    • 安全控制:存储过程可以对数据库中的数据进行严格的访问控制和权限管理
    • 数据一致性:存储过程可以实现复杂的数据操作和事务处理,确保数据的一致性和完整性

    缺点:

    • 创建和维护成本高:SQL 是一种结构化查询语言,难以处理复杂的业务逻辑
    • 开发调试复杂:需要通过特定的工具和技术进行,不方便调式
    • 可移植性差:存储过程通常依赖于特定的数据库平台和版本,不同的数据库系统之间存储过程的语法和特性可能有差异,导致存储过程的可移植性较差

    练习

    自定义函数

            function,可以使用自定义函数来扩展数据库的功能。

    创建函数

    create function 函数名([参数1数据类型[,参数2数据类型, …. ]])
    returns 返回值类型
    begin
        函数逻辑代码
    end;

    调用函数

    select 函数名([参数1,参数2 ... ]);

    删除函数

    drop function [if exists] 函数名;
    drop function if exists maxSal;
    create function maxSal ()
    returns int
    begin
        declare max sal int;
        select max (sal) into max sal from emp;
        return max sal;
    end;
    
    select maxSal () ;

    练习

    游标

            cursor,使用游标可以对存储过程或函数中的查询结果进行逐行处理

    • 创建游标后,可以使用 open 语句打开游标,开始执行游标指定的查询语句并生成结果集
    • 游标打开得到结果集后,可以使用 fetch 语句访问它的每一行
    • 游标处理完成后,应关闭游标,释放游标使用的内存和资源

    创建游标

    declare 游标名 cursor for 查询语句;

    打开游标

    open 游标名;

    读取游标数据到变量中

    fetch 游标名 into 变量名1[,变量名2 ... ];

    关闭游标

    close 游标名;

    多次读取游标中的数据

    检索单行数据

    create procedure test_cursor()
    begin
      #先声明变量
      declare emp_name varchar(20);
      
      #其次声明游标
      declare mycursor cursor
      for
      select ename from emp;
      
      #打开游标
      open mycursor;
      
      #依次取出游标中的数据
      fetch mycursor into emp_name;
      select emp_name;
      fetch mycursor into emp_name;
      select emp_name;
      fetch mycursor into emp_name;
      select emp_name;
      
      #关闭游标
      close mycuesor;
    end;

    指定循环次数检索数据

    create procedure test_cursor()
    begin
      #先声明变量
      declare emp_name varchar(20);
      declare a int default 0;
      
      #其次声明游标
      declare mycursor cursor
      for
      select ename from emp;
      
      #最后声明句柄
      declare continue handler for not found set done=1;
      
      #打开游标
      open mycursor;
      
      #依次取出游标中的数据
      while a<5 do
        fetch mycursor into emp_name;
        select emp_name;
        set a=a+1;
      end while;
      
      #关闭游标
      close mycuesor;
    end;

    指定循环条件检索数据(将游标中的数据全部读取出来)

    create procedure test_cursor()
    begin
      #先声明变量
      declare emp_name varchar(20);
      declare done int default 0;
      
      #其次声明游标
      declare mycursor cursor
      for
      select ename from emp;
      
      #最后声明句柄
      declare continue handler for not found set done=1;
      
      #打开游标
      open mycursor;
      
      #依次取出游标中的数据
      while done=0 do
        fetch mycursor into emp_name;
        select emp_name;
      end while;
      
      #关闭游标
      close mycuesor;
    end;

    在 emp 表中只有15条记录的情况下,上述代码会打印出16个结果, 第16次结果和第15次结果是一样的。在执行15次 while 循环之后,done 还是等于0的,所以会进入第16次循环,在执行 “fetch mycursor into emp_name;” 语句时,会出现找不到的错误,随后进行异常捕获(即句柄中的代码)将done的值改为1,确保下次不会进入循环,但是当前循环还要继续执行(即执行 “select emp_name;” ),由于该次循环没有对 emp_name 的值进行修改,所以还是上一次的值,故15和16次的结果相同。

    create procedure test_cursor()
    begin
      #先声明变量
      declare emp_name varchar(20);
      declare done int default 0;
      
      #其次声明游标
      declare mycursor cursor
      for
      select ename from emp;
      
      #最后声明句柄
      declare continue handler for not found set done=1;
      
      #打开游标
      open mycursor;
      
      #依次取出游标中的数据
      while done=0 do
        fetch mycursor into emp_name;
        if done=0 then
          select emp_name;
        end if;
      end while;
      
      #关闭游标
      close mycuesor;
    end;

    在 emp 表中只有15条记录的情况下,上述代码会打印出15个结果。

    练习 

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2316606.html

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

    相关文章

    图——表示与遍历

    图的两种主要表示方法 图有两种常用的表示方法&#xff0c;一种是邻接表法&#xff08;adjacency-list&#xff09;&#xff0c;另一种是邻接矩阵法&#xff08;adjacency-matrix&#xff09;。 邻接表法储存数据更紧凑&#xff0c;适合稀疏的图&#xff08;sparse graphs&am…

    新手村:数据预处理-异常值检测方法

    机器学习中异常值检测方法 一、前置条件 知识领域要求编程基础Python基础&#xff08;变量、循环、函数&#xff09;、Jupyter Notebook或PyCharm使用。统计学基础理解均值、中位数、标准差、四分位数、正态分布、Z-score等概念。机器学习基础熟悉监督/无监督学习、分类、聚类…

    ChatGPT-4

    第一章&#xff1a;ChatGPT-4的技术背景与核心架构 1.1 生成式AI的发展脉络 生成式人工智能&#xff08;Generative AI&#xff09;的演进历程可追溯至20世纪50年代的早期自然语言处理研究。从基于规则的ELIZA系统到统计语言模型&#xff0c;再到深度学习的革命性突破&#x…

    C语言_数据结构总结9:树的基础知识介绍

    1. 树的基本术语 - 祖先&#xff1a;考虑结点K&#xff0c;从根A到结点K的唯一路径上的所有其它结点&#xff0c;称为结点K的祖先。 - 子孙&#xff1a;结点B是结点K的祖先&#xff0c;结点K是B的子孙。结点B的子孙包括&#xff1a;E,F,K,L。 - 双亲&#xff1a;路径上…

    Python学习第十八天

    Django模型 定义&#xff1a;模型是 Django 中用于定义数据库结构的 Python 类。每个模型类对应数据库中的一张表&#xff0c;类的属性对应表的字段。 作用&#xff1a;通过模型&#xff0c;Django 可以将 Python 代码与数据库表结构关联起来&#xff0c;开发者无需直接编写 S…

    蓝桥杯备考:图论之Prim算法

    嗯。通过我们前面的学习&#xff0c;我们知道了&#xff0c;一个具有n个顶点的连通图&#xff0c;它的生成树包括n-1个边&#xff0c;如果边多一条就会变成图&#xff0c;少一条就不连通了 接下来我们来学一下把图变成生成树的一个算法 Prim算法&#xff0c;我们从任意一个结…

    langchain框架

    LangChain的架构分为多个层次&#xff0c;支持Python和JavaScript生态 基础层&#xff08;langchain-core&#xff09;&#xff1a;提供LLM抽象接口、表达式语言&#xff08;LCEL&#xff09;等核心机制&#xff0c;支持超过70种主流模型&#xff08;如GPT-4、Llama&#xff0…

    RHCE(RHCSA复习:npm、dnf、源码安装实验)

    七、软件管理 7.1 rpm 安装 7.1.1 挂载 [rootlocalhost ~]# ll /mnt total 0 drwxr-xr-x. 2 root root 6 Oct 27 21:32 hgfs[rootlocalhost ~]# mount /dev/sr0 /mnt #挂载 mount: /mnt: WARNING: source write-protected, mounted read-only. [rootlocalhost ~]# [rootlo…

    Mybatis3 调用存储过程

    1. 数据库MySQL&#xff0c;user表 CREATE TABLE user (USER_ID int NOT NULL AUTO_INCREMENT,USER_NAME varchar(100) NOT NULL COMMENT 用户姓名,AGE int NOT NULL COMMENT 年龄,CREATED_TIME datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,CREATED_BY varchar(100) NOT NUL…

    HiPixel开源AI驱动的图像超分辨率的原生macOS 应用程序,使用 SwiftUI 构建并利用 Upscayl 强大的 AI 模型

    一、软件介绍 文末提供程序和源码下载 HiPixel是一个开源程序基于SwiftUI构建的macOS原生应用程序&#xff0c;用于AI驱动的图像超分辨率&#xff0c;并利用Upscayl的强大AI模型。 二、软件特征 具有 SwiftUI 界面的原生 macOS 应用程序使用 AI 模型进行高质量图像放大通过 G…

    缓存和客户端数据存储体系(Ark Data Kit)--- 应用数据持久化(首选项持久化、K-V、关系型数据库)持续更新中...

    Core File Kit做怎删改查操作不便&#xff0c;用Ark Data Kit。 功能介绍 ArkData &#xff08;方舟数据管理&#xff09;为开发者提供数据存储、数据管理和数据同步能力&#xff0c;比如联系人应用数据可以保存到数据库中&#xff0c;提供数据库的安全、可靠以及共享访问等管…

    本地部署OpenManus及原理介绍

    概述&#xff1a; 最近Minaus特别火&#xff0c;随后开源社区就有项目尝试复刻Minaus&#xff0c;项目名称为OpenManus&#xff0c;原理是用推理模型为决策者&#xff0c;将我们输入的问题进行分解后调用本地工具执行。 OpenManus安装&#xff1a; 本人在Ubuntu桌面版本上安装…

    高效手机检测:视觉分析技术的优势

    在当今社会&#xff0c;手机已成为人们日常生活和工作中不可或缺的工具。然而&#xff0c;在某些特定场合&#xff0c;如考场、工作场所等&#xff0c;手机的使用却可能带来负面影响。因此&#xff0c;如何有效监测和防止在这些场合偷用手机的行为&#xff0c;成为了一个亟待解…

    Spring Boot配置类原理、Spring Boot核心机制理解,以及实现自动装置的底层原理

    目的:从底层源码角度分析 Spring Boot 配置类以及自动装载的底层原理 文章目录 1. Spring Boot 配置类实现自动装载1.1 @Configuration注解1.2 @Configuration 注解完成 bean 注入流程图1.3 @ConfigurationProperties注解赋值2. Spring Boot的核心机制:自动装配2.1 @SpringBo…

    01-Canvas-使用fabric初始

    fabric官网&#xff1a; https://fabric5.fabricjs.com/demos/ 创建画布并绘制 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…

    树莓派 连接 PlutoSDR 教程

    在树莓派5上安装PlutoSDR&#xff08;ADALM-Pluto&#xff09;的驱动程序&#xff0c;主要需要安装相关的库和工具&#xff0c;以便与PlutoSDR通信&#xff0c;比如libiio和libad9361&#xff0c;并确保系统能够识别设备。由于树莓派5运行的是基于Linux的系统&#xff08;通常是…

    Git使用(二)--如何配置 GitHub 远程仓库及本地 Git 环境

    在日常的开发过程中&#xff0c;使用版本控制工具 Git 是一个非常重要的技能&#xff0c;特别是对于管理和协作开发。通过 GitHub&#xff0c;我们可以轻松地进行代码版本管理和共享。这篇博客将带您一步步学习如何配置 Git 环境并将本地仓库与 GitHub 远程仓库连接起来。 一、…

    在Pycharm配置conda虚拟环境的Python解释器

    〇、前言 今天在配置python解释器时遇到了这样的问题 经过一下午自行摸索、上网搜寻后&#xff0c;终于找到的解决的方案&#xff0c;遂将该方法简要的记录下来&#xff0c;以备后用&#xff0c;并希望能帮助到有同样问题或需求的朋友:) 我所使用的软件的版本如下&#xff0c;假…

    零基础keil:设置注释快捷键

    1.打开快捷键设置&#xff1a; 在Keil中&#xff0c;选择菜单栏中的“Settings”&#xff0c;然后选择“Shortcuts”来打开快捷键设置界面。 2.选择注释命令&#xff1a; 在快捷键设置界面中&#xff0c;找到与注释相关的命令&#xff0c;如“Comment Selection”&#xff0…

    Java中关于Optional的 orElse 操作,以及 orElse 与 orElseGet 的区别

    文章目录 1. 大概说明2. 详细分析2.1 .orElse 操作2.2 .orElse 的作用&#xff1a;避免空指针异常2.3 为什么要用&#xff1f;2.4 orElseGet如何使用2.5 orElse和orElseGet的区别 1. 大概说明 这篇文章的目的是为了说明&#xff1a; orElse 如何使用orElseGet 如何使用两者的…