mysql 存储过程和自定义函数 详解
首先创建存储过程或者自定义函数时,都要使用use database 切换到目标数据库,因为存储过程和自定义函数都是属于某个数据库的。
存储过程是一种预编译的 SQL 代码集合,封装在数据库对象中。以下是一些常见的存储过程的关键字:
存储过程
1. 存储过程的定义
-
CREATE PROCEDURE: 用于创建一个新的存储过程。
CREATE PROCEDURE procedure_name (parameter_list) BEGIN-- 存储过程体 END; -
DROP PROCEDURE: 用于删除已存在的存储过程。
DROP PROCEDURE procedure_name;
2. 参数定义
-
IN: 表示输入参数。
-
OUT: 表示输出参数。
-
INOUT: 表示既可以输入又可以输出的参数。
CREATE PROCEDURE my_procedure(IN param1 INT, OUT param2 INT) BEGIN-- 存储过程体 END;
3. 变量声明与操作
-
DECLARE: 定义局部变量、条件和游标。
DECLARE var1 INT DEFAULT 0; DECLARE var2 VARCHAR(50); -
SET: 用于给变量赋值。
SET var1 = 10;
4. 控制流程
-
BEGIN/END: 标记存储过程块的开始和结束。
BEGIN-- 存储过程体 END; -
IF 条件判断
IF语句用于简单的条件分支。语法格式:
IF condition THENSQL逻辑 ELSEIF condition THENSQL逻辑 ELSESQL逻辑 END IF;案例:
根据用户 ID 返回不同的信息。
DELIMITER // CREATE PROCEDURE CheckUser(IN userId VARCHAR(32)) BEGINDECLARE userName VARCHAR(32);IF userId = 'APP-2016-00494878' THENSELECT username INTO userName FROM users WHERE userid = userId;SELECT userName;ELSEIF userId = 'APP-2016-7777777' THENSELECT userage INTO userName FROM users WHERE userid = userId;SELECT userName;ELSESELECT userId;END IF; END // DELIMITER ;调用存储过程:
CALL CheckUser('APP-2016-00494878'); -
CASE: 用于多条件判断。
-
语法格式:
CASEWHEN condition1 THENSQL逻辑WHEN condition2 THENSQL逻辑ELSESQL逻辑 END CASE; -
根据用户角色返回不同的权限级别。
-
DELIMITER // CREATE PROCEDURE GetUserRole(IN userId INT) BEGINDECLARE userRole VARCHAR(20);SELECT role INTO userRole FROM users WHERE id = userId;CASE userRoleWHEN 'admin' THENSELECT 'Administrator';WHEN 'user' THENSELECT 'Standard User';ELSESELECT 'Guest';END CASE; END // DELIMITER ;调用存储过程:
CALL GetUserRole(1); -
LOOP/WHILE/REPEAT: 实现循环操作。
LOOP_LABEL: LOOP-- 循环体IF condition THENLEAVE LOOP_LABEL;END IF; END LOOP;
WHILE 循环
WHILE 循环在条件为真时执行循环体中的 SQL 语句。
语法格式:
WHILE 条件 DOSQL逻辑
END WHILE;
案例:
计算从 1 累加到 n 的值,n 为传入的参数值。
DELIMITER //
CREATE PROCEDURE CalculateSum(IN n INT)
BEGINDECLARE total INT DEFAULT 0;WHILE n > 0 DOSET total = total + n;SET n = n - 1;END WHILE;SELECT total;
END //
DELIMITER ;
调用存储过程:
CALL CalculateSum(100);
REPEAT 循环
REPEAT 循环至少执行一次循环体中的 SQL 语句,直到条件为真时退出循环。
语法格式:
REPEATSQL逻辑
UNTIL 条件
END REPEAT;
案例:
计算从 1 累加到 n 的值,n 为传入的参数值。
DELIMITER //
CREATE PROCEDURE CalculateSumRepeat(IN n INT)
BEGINDECLARE total INT DEFAULT 0;REPEATSET total = total + n;SET n = n - 1;UNTIL n <= 0END REPEAT;SELECT total;
END //
DELIMITER ;
调用存储过程:
CALL CalculateSumRepeat(100);
LOOP 循环
LOOP 循环是无条件循环,通常与 LEAVE 语句结合使用来退出循环。
语法格式:
[loop_label:] LOOPSQL逻辑
END LOOP [loop_label];
案例:
计算从 1 累加到 n 的值,n 为传入的参数值。
DELIMITER //
CREATE PROCEDURE CalculateSumLoop(IN n INT)
BEGINDECLARE total INT DEFAULT 0;sum_loop: LOOPIF n <= 0 THENLEAVE sum_loop;END IF;SET total = total + n;SET n = n - 1;END LOOP sum_loop;SELECT total;
END //
DELIMITER ;
调用存储过程:
CALL CalculateSumLoop(100);
5. 条件处理
-
DECLARE HANDLER: 定义异常处理程序。
DECLARE CONTINUE HANDLER FOR SQL_ERROR_CODE error_code BEGIN-- 异常处理语句 END;
6. 游标操作
-
DECLARE CURSOR: 声明游标。
DECLARE cursor_name CURSOR FOR SELECT column1, column2 FROM table WHERE condition; -
OPEN CURSOR: 打开游标。
OPEN cursor_name; -
FETCH CURSOR: 读取游标数据。
FETCH cursor_name INTO var1, var2; -
CLOSE CURSOR: 关闭游标。
CLOSE cursor_name;
7. 调试与优化
-
SET: 调整优化器参数。
SET optimizer_switch = 'index_merge=on'; -
SHOW VARIABLES: 查看系统变量。
SHOW VARIABLES LIKE 'optimizer_switch';
8.案例
以下是一个包含事务处理的存储过程示例:
DELIMITER //CREATE PROCEDURE transfer_funds(IN from_account INT, IN to_account INT, IN amount DECIMAL(10,2))
BEGINSTART TRANSACTION;IF amount > 0 THEN-- 从源账户扣除金额UPDATE accounts SET balance = balance - amount WHERE id = from_account;-- 向目标账户增加金额UPDATE accounts SET balance = balance + amount WHERE id = to_account;-- 提交事务COMMIT;ELSE-- 回滚事务ROLLBACK;END IF;
END //DELIMITER ;
这个存储过程通过事务确保资金转账操作的原子性。
9.补充知识:游标
注意事项
-
游标只能在存储过程和函数中使用。
-
游标是只读的,不能用于修改数据,但可以通过
SELECT查询结果集。 -
需要显式地打开和关闭游标,以确保资源的正确释放。
通过使用游标,可以对查询结果集进行逐行处理,这对于需要对每行数据执行复杂操作的场景非常有用
DELIMITER //
CREATE PROCEDURE ProcessOrders()
BEGINDECLARE done INT DEFAULT 0;DECLARE orderId INT;DECLARE orderStatus VARCHAR(20);-- 声明一个名为 cur 的游标。-- 该游标基于查询 SELECT id, status FROM orders,用于存储查询结果集。-- 可以通过游标逐行访问和操作 orders 表中的每一行数据。DECLARE cur CURSOR FOR SELECT id, status FROM orders;-- 定义一个异常处理程序,当游标遍历完所有行(触发 NOT FOUND 异常)时,将变量 done 设置为 1。DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;OPEN cur; -- 打开游标order_loop: LOOPFETCH cur INTO orderId, orderStatus; -- 从游标中提取数据IF done THENLEAVE order_loop; -- 如果没有更多数据,退出循环END IF;-- 在这里处理每一行数据UPDATE orders SET status = 'processed' WHERE id = orderId;END LOOP order_loop;CLOSE cur; -- 关闭游标
END //
DELIMITER ;
在这个存储过程中,当游标遍历完所有行时,FETCH cur INTO orderId, orderStatus 会触发 NOT FOUND 异常。此时,CONTINUE HANDLER 将 done 设置为 1,退出循环。
通过这种方式,可以优雅地处理游标遍历完成的情况,确保程序不会因异常而中断。
10.查询当前数据库有哪些存储过程
SELECT SPECIFIC_NAME AS '存储过程名', ROUTINE_SCHEMA AS '数据库名', CREATED AS '创建时间', LAST_ALTERED AS '最后修改时间'
FROM information_schema.ROUTINES
WHERE ROUTINE_TYPE = 'PROCEDURE'AND ROUTINE_SCHEMA = 'test_mybatis';
自定义函数
1. 定义自定义函数
-
CREATE FUNCTION: 用于创建一个新的自定义函数。
CREATE FUNCTION function_name (parameter_list) RETURNS return_type BEGIN-- 函数体 END;-
function_name: 函数名称。
-
parameter_list: 参数列表,参数可以是
IN类型。 -
RETURNS: 指定函数返回值的类型。
-
2. 参数定义
-
IN: 定义输入参数。MySQL 的自定义函数只支持
IN类型的参数。CREATE FUNCTION add_numbers(IN a INT, IN b INT) RETURNS INT BEGINRETURN a + b; END;
3. 函数体
-
BEGIN/END: 标记函数体的开始和结束。
BEGIN-- 函数逻辑 END;
4. 返回值
-
RETURN: 用于返回函数的计算结果。
RETURN value;
5. 属性
-
DETERMINISTIC 或 NOT DETERMINISTIC: 标记函数是否是确定性的。
-
确定性函数:对于相同的输入参数总是返回相同的结果。
-
非确定性函数:对于相同的输入参数可能返回不同的结果。
CREATE FUNCTION function_name (parameter_list) RETURNS return_type DETERMINISTIC BEGIN-- 函数逻辑 END; -
6. 修改或删除函数
-
ALTER FUNCTION: 修改已存在的自定义函数。
-
DROP FUNCTION: 删除已存在的自定义函数。
DROP FUNCTION function_name;
7. 调用函数
-
可以直接在 SQL 语句中调用自定义函数。
SELECT add_numbers(5, 10);
存储过程和自定义函数区别
| 特性 | 存储过程 | 自定义函数 |
|---|---|---|
| 定义 | 是一组预编译的 SQL 语句和流程控制语句的集合,可以包含多个 SQL 语句和复杂逻辑。 | 是一个用户定义的函数,用于封装特定的功能逻辑,返回一个值。 |
| 返回值 | 可以没有返回值,也可以通过 OUT 参数返回多个值。 | 必须返回一个值,返回值类型在创建函数时指定。 |
| 参数类型 | 支持 IN、OUT 和 INOUT 类型的参数。 | 只支持 IN 类型的参数。 |
| 调用方式 | 使用 CALL 语句调用,不能在 SELECT 中直接调用。 | 可以在 SQL 语句中直接调用,如 SELECT、WHERE、ORDER BY 等。 |
| 事务处理 | 可以包含事务操作,控制事务的提交和回滚。 | 不支持事务操作。 |
| 代码重用 | 适合封装复杂的业务逻辑,便于维护和代码重用。 | 适合封装简单的逻辑,如计算、转换或条件判断,便于在多个地方重用。 |
| 性能 | 存储过程在服务器端执行,与应用程序交互次数少,性能较高。 | 自定义函数在查询中调用时,可能会导致性能问题,需要谨慎使用。 |
| 适用场景 | 适用于执行复杂操作的场景,如批量更新数据、执行多个 SQL 语句或返回结果集。 | 适用于需要返回单个值的场景,如计算、转换或简单的逻辑判断。 |
总结
-
存储过程:适合执行复杂的操作,可以返回多个值或结果集,适用于批量更新数据、执行多个 SQL 语句或返回结果集等场景。
-
自定义函数:适合返回单个值的简单逻辑,可以直接在 SQL 语句中调用,适用于计算、转换或条件判断等场景。
相关文章:
mysql 存储过程和自定义函数 详解
首先创建存储过程或者自定义函数时,都要使用use database 切换到目标数据库,因为存储过程和自定义函数都是属于某个数据库的。 存储过程是一种预编译的 SQL 代码集合,封装在数据库对象中。以下是一些常见的存储过程的关键字: 存…...
Maven 中常用的 scope 类型及其解析
在 Maven 中,scope 属性用于指定依赖项的可见性及其在构建生命周期中的用途。不同的 scope 类型能够影响依赖项的编译和运行阶段。以下是 Maven 中常用的 scope 类型及其解析: compile(默认值): 这是默认的作用域。如果…...
SpringCloud - Nacos注册/配置中心
前言 该博客为Nacos学习笔记,主要目的是为了帮助后期快速复习使用 学习视频:7小快速通关SpringCloud 辅助文档:SpringCloud快速通关 源码地址:cloud-demo 一、简介 Nacos官网:https://nacos.io/docs/next/quickstar…...
C++ 继承(1)
1.继承概念 我们平时有时候在写多个有内容重复的类的时候会很麻烦 比如我要写Student Teacher Staff 这三个类 里面都要包含 sex name age成员变量 唯一不同的可能有一个成员变量 但是这三个成员变量我要写三遍 太麻烦了 有没有好的方式呢? 有的 就是继承…...
【C语言】传值调用与传址调用详解
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 💯前言💯传值调用1. 什么是传值调用?2. 示例代码:传值调用失败的情况执行结果: 3. 为什么传值调用无法修改外部变量? Ǵ…...
蓝桥杯C语言组:图论问题
蓝桥杯C语言组图论问题研究 摘要 图论是计算机科学中的一个重要分支,在蓝桥杯C语言组竞赛中,图论问题频繁出现,对参赛选手的算法设计和编程能力提出了较高要求。本文系统地介绍了图论的基本概念、常见算法及其在蓝桥杯C语言组中的应用&#…...
windows通过网络向Ubuntu发送文件/目录
由于最近要使用树莓派进行一些代码练习,但是好多东西都在windows里或虚拟机上,就想将文件传输到树莓派上,但试了发现u盘不能简单传送,就在网络上找到了通过windows 的scp命令传送 前提是树莓派先开启ssh服务,且Window…...
Unity抖音云启动测试:如何用cmd命令行启动exe
相关资料:弹幕云启动(原“玩法云启动能力”)_直播小玩法_抖音开放平台 1,操作方法 在做云启动的时候,接完发现需要命令行模拟云环境测试启动,所以研究了下。 首先进入cmd命令,CD进入对应包的文件…...
ZU47DR 100G光纤 高性能板卡
简介 2347DR是一款最大可提供8路ADC接收和8路DAC发射通道的高性能板卡。板卡选用高性价比的Xilinx的Zynq UltraScale RFSoC系列中XCZU47DR-FFVE1156作为处理芯片(管脚可以兼容XCZU48DR-FFVE1156,主要差别在有无FEC(信道纠错编解码࿰…...
【算法】动态规划专题⑥ —— 完全背包问题 python
目录 前置知识进入正题模板 前置知识 【算法】动态规划专题⑤ —— 0-1背包问题 滚动数组优化 完全背包问题是动态规划中的一种经典问题,它与0-1背包问题相似,但有一个关键的区别:在完全背包问题中,每种物品都有无限的数量可用。…...
MySQL——表操作及查询
一.表操作 MySQL的操作中,一些专用的词无论是大写还是小写都是可以通过的。 1.插入数据 INSERT [INTO] table_name (列名称…)VALUES (列数据…), (列数据…); "[]"表示可有可无,插入时,如果不指定要插入的列,则表示默…...
SAP-ABAP:ROLLBACK WORK使用详解
在SAP ABAP 中,ROLLBACK WORK 语句用于回滚当前事务(LUW,Logical Unit of Work),撤销自上次提交或回滚以来的所有数据库更改。它通常与 COMMIT WORK 配合使用,确保数据一致性。 关键点: 回滚作…...
C#中深度解析BinaryFormatter序列化生成的二进制文件
C#中深度解析BinaryFormatter序列化生成的二进制文件 BinaryFormatter序列化时,对象必须有 可序列化特性[Serializable] 一.新建窗体测试程序BinaryDeepAnalysisDemo,将默认的Form1重命名为FormBinaryDeepAnalysis 二.新建测试类Test Test.cs源程序如下: using System; us…...
Git提交错误解决:missing Change-Id in message footer
问题现象: 提交的commit中没有插入change id导致push代码失败。 问题解决: 针对该错误,Git已经给出了解决方案: 1、to automatically insert a Change-Id, install the hook: gitdir$(git rev-parse --git-dir); scp -p -P 2…...
51单片机之引脚图(详解)
8051单片机引脚分类与功能笔记 1. 电源引脚 VCC(第40脚):接入5V电源,为单片机提供工作电压。GND(第20脚):接地端,确保电路的电位参考点。 2.时钟引脚 XTAL1(第19脚&a…...
jupyterLab插件开发
jupyter lab安装、配置: jupyter lab安装、配置教程_容器里装jupyterlab-CSDN博客 『Linux笔记』服务器搭建神器JupyterLab_linux_布衣小张-腾讯云开发者社区 Jupyter Lab | 安装、配置、插件推荐、多用户使用教程-腾讯云开发者社区-腾讯云 jupyterLab插件开发教…...
配置#include “nlohmann/json.hpp“,用于处理json文件
#include “nlohmann/json.hpp” // 需要安装 nlohmann/json.hpp 头文件 using json = nlohmann::json; 下载链接:https://github.com/nlohmann/json/tree/develop 1.下载并解压:首先,需要从nlohmann/json的GitHub仓库下载源代码,并解压得到的文件。 地址: nlohmann/json…...
MATLAB | 基于Theil-Sen斜率和Mann-Kendall检验的栅格数据趋势分析
最近看到一些博主分享关于 SenMK 检验的代码,对于新手来说可能有点复杂。我们编写了一段 MATLAB 代码,能够一次性解决这些问题,简化操作流程。我们还准备了几个关于趋势检验的空间分布图,供大家参考。 一、Sens Slope和Mann-Kenda…...
python连点器
要实现一个用于抖音点赞的鼠标连点工具,可以通过编程或现有软件实现。以下是两种常见方法(但请注意:频繁自动化操作可能违反平台规则,需谨慎使用): 方法 1:使用现成工具(如 AutoClic…...
C#程式状态机及其Godot实践
前言 今天是周日,马上就要迎来新的一周了,前几周都没干什么事,为了减缓偷懒症状,立个Flag从今往后每周至少更新两次文章。内容虽然无法保证优质,但重在坚持,全当写周记了。希望不要三分钟热度吧。 今天记录…...
Windows 系统下使用 Ollama 离线部署 DeepSeek - R1 模型指南
引言 随着人工智能技术的飞速发展,各类大语言模型层出不穷。DeepSeek - R1 凭借其出色的语言理解和生成能力,受到了广泛关注。而 Ollama 作为一款便捷的模型管理和部署工具,能够帮助我们轻松地在本地环境中部署和使用模型。本文将详细介绍如…...
Docker、Ollama、Dify 及 DeepSeek 安装配置与搭建企业级本地私有化知识库实践
在现代企业中,管理和快速访问知识库是提升工作效率、促进创新的关键。为了满足这些需求,企业越来越倾向于构建本地私有化的知识库系统,这样可以更好地保护企业数据的安全性和隐私性。本文将介绍如何利用 **Docker**、**Ollama**、**Dify** 和…...
【漫话机器学习系列】087.常见的神经网络最优化算法(Common Optimizers Of Neural Nets)
常见的神经网络优化算法 1. 引言 在深度学习中,优化算法(Optimizers)用于更新神经网络的权重,以最小化损失函数(Loss Function)。一个高效的优化算法可以加速训练过程,并提高模型的性能和稳定…...
react-native fetch在具有http远程服务器后端的Android设备上抛出“Network request failed“错误
问题描述: 在具有http远程服务器后端的Android设备上,使用react-native fetch时抛出"Network request failed"错误。 回答: "Network request failed"错误通常表示在进行网络请求时出现了问题。可能的原因包括网络连接…...
【JVM详解四】执行引擎
一、概述 Java程序运行时,JVM会加载.class字节码文件,但是字节码并不能直接运行在操作系统之上,而JVM中的执行引擎就是负责将字节码转化为对应平台的机器码让CPU运行的组件。 执行引擎是JVM核心的组成部分之一。可以把JVM架构分成三部分&am…...
route 与 router 之间的差别
简述: router:主要用于处理一些动作, route:主要获得或处理一些数据,比如地址、参数等 例: videoInfo1.vue: <template><div class"video-info"><h3>二级组件…...
[vue3] Ref Reactive
【b站-【前端面试】Vue3 ref 与 reactive 区别】 Ref:Ref用于创建一个响应式的基本数据类型,比如数字、字符串等。它将普通的数据变成响应式数据,可以监听数据的变化。使用Ref时,我们可以通过.value来访问和修改数据的值。 Reac…...
SamWaf开源轻量级的网站应用防火墙(安装包),私有化部署,加密本地存储的数据,易于启动,并支持 Linux 和 Windows 64 位和 Arm64
一、SamWaf轻量级开源防火墙介绍 (文末提供下载) SamWaf网站防火墙是一款适用于小公司、工作室和个人网站的开源轻量级网站防火墙,完全私有化部署,数据加密且仅保存本地,一键启动,支持Linux,Wi…...
极客说|利用 Azure AI Agent Service 创建自定义 VS Code Chat participant
作者:卢建晖 - 微软高级云技术布道师 「极客说」 是一档专注 AI 时代开发者分享的专栏,我们邀请来自微软以及技术社区专家,带来最前沿的技术干货与实践经验。在这里,您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&a…...
22.2、Apache安全分析与增强
目录 Apache Web安全分析与增强 - Apache Web概述Apache Web安全分析与增强 - Apache Web安全威胁Apache Web安全机制Apache Web安全增强 Apache Web安全分析与增强 - Apache Web概述 阿帕奇是一个用于搭建WEB服务器的应用程序,它是开源的,它的配置文件…...
