玩转Mysql系列 - 第17篇:存储过程自定义函数详解

这是Mysql系列第17篇。

环境:mysql5.7.25,cmd命令中进行演示。

代码中被[]包含的表示可选,|符号分开的表示可选其一。

需求背景介绍

线上程序有时候出现问题导致数据错误的时候,如果比较紧急,我们可以写一个存储来快速修复这块的数据,然后再去修复程序,这种方式我们用到过不少。

存储过程相对于java程序对于java开发来说,可能并不是太好维护以及阅读,所以不建议在程序中去调用存储过程做一些业务操作。

关于自定义函数这块,若mysql内部自带的一些函数无法满足我们的需求的时候,我们可以自己开发一些自定义函数来使用。

所以建议大家掌握mysql中存储过程和自定义函数这块的内容。

本文内容

  • 详解存储过程的使用

  • 详解自定义函数的使用

准备数据

/*建库javacode2018*/
drop database if exists javacode2018;
create database javacode2018;/*切换到javacode2018库*/
use javacode2018;/*建表test1*/
DROP TABLE IF EXISTS t_user;
CREATE TABLE t_user (id   INT NOT NULL PRIMARY KEY COMMENT '编号',age  SMALLINT UNSIGNED NOT NULL COMMENT '年龄',name VARCHAR(16) NOT NULL COMMENT '姓名'
) COMMENT '用户表';

存储过程

概念

一组预编译好的sql语句集合,理解成批处理语句。

好处:

  • 提高代码的重用性

  • 简化操作

  • 减少编译次数并且减少和数据库服务器连接的次数,提高了效率。

创建存储过程

create procedure 存储过程名([参数模式] 参数名 参数类型)
begin存储过程体
end

参数模式有3种:

in:该参数可以作为输入,也就是该参数需要调用方传入值。

out:该参数可以作为输出,也就是说该参数可以作为返回值。

inout:该参数既可以作为输入也可以作为输出,也就是说该参数需要在调用的时候传入值,又可以作为返回值。

参数模式默认为IN。

一个存储过程可以有多个输入、多个输出、多个输入输出参数。

调用存储过程

call 存储过程名称(参数列表);

注意:调用存储过程关键字是call

删除存储过程

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

存储过程只能一个个删除,不能批量删除。

if exists:表示存储过程存在的情况下删除。

修改存储过程

存储过程不能修改,若涉及到修改的,可以先删除,然后重建。

查看存储过程

show create procedure 存储过程名称;

可以查看存储过程详细创建语句。

示例

示例1:空参列表

创建存储过程

/*设置结束符为$*/
DELIMITER $
/*如果存储过程存在则删除*/
DROP PROCEDURE IF EXISTS proc1;
/*创建存储过程proc1*/
CREATE PROCEDURE proc1()BEGININSERT INTO t_user VALUES (1,30,'路人甲Java');INSERT INTO t_user VALUES (2,50,'刘德华');END $/*将结束符置为;*/
DELIMITER ;

delimiter用来设置结束符,当mysql执行脚本的时候,遇到结束符的时候,会把结束符前面的所有语句作为一个整体运行,存储过程中的脚本有多个sql,但是需要作为一个整体运行,所以此处用到了delimiter。

mysql默认结束符是分号。

上面存储过程中向t_user表中插入了2条数据。

调用存储过程:

CALL proc1();

验证效果:

mysql> select * from t_user;
+----+-----+---------------+
| id | age | name          |
+----+-----+---------------+
|  1 |  30 | 路人甲Java    |
|  2 |  50 | 刘德华        |
+----+-----+---------------+
2 rows in set (0.00 sec)

存储过程调用成功,test1表成功插入了2条数据。

示例2:带in参数的存储过程

创建存储过程:

/*设置结束符为$*/
DELIMITER $
/*如果存储过程存在则删除*/
DROP PROCEDURE IF EXISTS proc2;
/*创建存储过程proc2*/
CREATE PROCEDURE proc2(id int,age int,in name varchar(16))BEGININSERT INTO t_user VALUES (id,age,name);END $/*将结束符置为;*/
DELIMITER ;

调用存储过程:

/*创建了3个自定义变量*/
SELECT @id:=3,@age:=56,@name:='张学友';
/*调用存储过程*/
CALL proc2(@id,@age,@name);

验证效果:

mysql> select * from t_user;
+----+-----+---------------+
| id | age | name          |
+----+-----+---------------+
|  1 |  30 | 路人甲Java    |
|  2 |  50 | 刘德华        |
|  3 |  56 | 张学友        |
+----+-----+---------------+
3 rows in set (0.00 sec)

张学友插入成功。

示例3:带out参数的存储过程

创建存储过程:

delete a from t_user a where a.id = 4;
/*如果存储过程存在则删除*/
DROP PROCEDURE IF EXISTS proc3;
/*设置结束符为$*/
DELIMITER $
/*创建存储过程proc3*/
CREATE PROCEDURE proc3(id int,age int,in name varchar(16),out user_count int,out max_id INT)BEGININSERT INTO t_user VALUES (id,age,name);/*查询出t_user表的记录,放入user_count中,max_id用来存储t_user中最小的id*/SELECT COUNT(*),max(id) into user_count,max_id from t_user;END $/*将结束符置为;*/
DELIMITER ;

proc3中前2个参数,没有指定参数模式,默认为in。

调用存储过程:

/*创建了3个自定义变量*/
SELECT @id:=4,@age:=55,@name:='郭富城';
/*调用存储过程*/
CALL proc3(@id,@age,@name,@user_count,@max_id);

验证效果:

mysql> select @user_count,@max_id;
+-------------+---------+
| @user_count | @max_id |
+-------------+---------+
|           4 |       4 |
+-------------+---------+
1 row in set (0.00 sec)
示例4:带inout参数的存储过程

创建存储过程:

/*如果存储过程存在则删除*/
DROP PROCEDURE IF EXISTS proc4;
/*设置结束符为$*/
DELIMITER $
/*创建存储过程proc4*/
CREATE PROCEDURE proc4(INOUT a int,INOUT b int)BEGINSET a = a*2;select b*2 into b;END $/*将结束符置为;*/
DELIMITER ;

调用存储过程:

/*创建了2个自定义变量*/
set @a=10,@b:=20;
/*调用存储过程*/
CALL proc4(@a,@b);

验证效果:

mysql> SELECT @a,@b;
+------+------+
| @a   | @b   |
+------+------+
|   20 |   40 |
+------+------+
1 row in set (0.00 sec)

上面的两个自定义变量@a、@b作为入参,然后在存储过程内部进行了修改,又作为了返回值。

示例5:查看存储过程
mysql> show create procedure proc4;
+-------+-------+-------+-------+-------+-------+
| Procedure | sql_mode | Create Procedure | character_set_client | collation_connection | Database Collation |
+-------+-------+-------+-------+-------+-------+
| proc4     | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`localhost` PROCEDURE `proc4`(INOUT a int,INOUT b int)
BEGINSET a = a*2;select b*2 into b;END | utf8                 | utf8_general_ci      | utf8_general_ci    |
+-------+-------+-------+-------+-------+-------+
1 row in set (0.00 sec)

函数

概念

一组预编译好的sql语句集合,理解成批处理语句。类似于java中的方法,但是必须有返回值。

创建函数

create function 函数名(参数名称 参数类型)
returns 返回值类型
begin函数体
end

参数是可选的。

返回值是必须的。

调用函数

select 函数名(实参列表);

删除函数

drop function [if exists] 函数名;

查看函数详细

show create function 函数名;

示例

示例1:无参函数

创建函数:

/*删除fun1*/
DROP FUNCTION IF EXISTS fun1;
/*设置结束符为$*/
DELIMITER $
/*创建函数*/
CREATE FUNCTION fun1()returns INTBEGINDECLARE max_id int DEFAULT 0;SELECT max(id) INTO max_id FROM t_user;return max_id;END $
/*设置结束符为;*/
DELIMITER ;

调用看效果:

mysql> SELECT fun1();
+--------+
| fun1() |
+--------+
|      4 |
+--------+
1 row in set (0.00 sec)
示例2:有参函数

创建函数:

/*删除函数*/
DROP FUNCTION IF EXISTS get_user_id;
/*设置结束符为$*/
DELIMITER $
/*创建函数*/
CREATE FUNCTION get_user_id(v_name VARCHAR(16))returns INTBEGINDECLARE r_id int;SELECT id INTO r_id FROM t_user WHERE name = v_name;return r_id;END $
/*设置结束符为;*/
DELIMITER ;

运行看效果:

mysql> SELECT get_user_id(name) from t_user;
+-------------------+
| get_user_id(name) |
+-------------------+
|                 1 |
|                 2 |
|                 3 |
|                 4 |
+-------------------+
4 rows in set (0.00 sec)

存储过程和函数的区别

存储过程的关键字为procedure,返回值可以有多个,调用时用call一般用于执行比较复杂的的过程体、更新、创建等语句

函数的关键字为function返回值必须有一个,调用用select,一般用于查询单个值并返回。

存储过程函数
返回值可以有0个或者多个必须有一个
关键字procedurefunction
调用方式callselect

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

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

相关文章

亚马逊鲲鹏系统多渠道引流功能快速增加你的listing流量

如果亚马逊Listing没有流量,那么亚马逊产品排名也会在很靠后的位置,从而就会导致吸引不到客户点击进行下单购买,因此引流就很重要了,普通的引流方法很难达到效果,并且还会花费大量的时间,那么我们可以用亚马…

【postgresql 基础入门】数据库服务的管理,启动、停止、状态查看、配置加载、重启都在这里

数据库服务管理 ​专栏内容: postgresql内核源码分析手写数据库toadb并发编程 ​开源贡献: toadb开源库 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤&#xff…

JMeter压力测试 5分钟让你学会如何并发压测接口

文章目录 地址下载启动 使用 地址 JMeter官网下载:https://jmeter.apache.org/download_jmeter.cgi 下载 最新款的jmeter需要java8的支持,请自行安装jdk8或以上的版本 根据系统不同系统下载zip或者是tgz格式的压缩包,并解压,博…

企业互联网暴露面未知资产梳理

一、互联网暴露面梳理的重要性 当前,互联网新技术的产生推动着各种网络应用的蓬勃发展,网络安全威胁逐渐蔓延到各种新兴场景中,揭示着网络安全威胁不断加速泛化。当前网络存在着许多资产,这些资产关系到企业内部的安全情况&#…

【Chrome】chrome浏览器未连接到互联网

问题描述 电脑上安装了一个联想电脑管家,进行了一下清理,并优化了一下启动项,Chrome浏览器突然什么网站都无法访问了。以为更新坏了,但相同的网站放到火狐浏览器上,竟然可以打开,怎么回事呢?怎…

报错:axios 发送的接口请求 404

axios 发送的接口请求 404 一、问题二、分析 一、问题 二、分析 axios 发送的接口请求 404,根本没有把接口信息发送到后端,这个时候你可以查看检查一下自己的接口名字,或让后端配合换一个接口名字再发送一次接口请求 或者重启一下电脑 我是…

微调chatGLM-6B大模型的方法

GLM官方的知乎微调教程:https://zhuanlan.zhihu.com/p/618498001 GLM官方的GitHub微调教程:https://github.com/THUDM/ChatGLM-6B/tree/main/ptuning 说这个微调出的模型和原模型是同时加载的,输入文本的时候会先看看微调出的模型有没有存相应…

c++图论免费ppt,简单深度理解图论

本篇博文想分享一个ppt,是帮助大家简单深度理解c图论. 作者承诺:分享的东西没有病毒,是资料。 分享的东西一个是ppt,ppt里面是150页的,里面将带领大家简单深度理解c图论,还有一个就是里面例题的数据,大家可以按照数据…

Android 9.0 pms获取应用列表时过滤掉某些app功能实现

1.前言 在9.0的系统rom定制化开发中,对系统定制的功能也是很多的,在一次产品开发中,要求在第三方app获取应用列表的时候,需要过滤掉某些app,就是不显示在app应用列表中,这就需要在pms查询app列表时过滤掉这些app就可以了,接下来就实现这些功能 2.pms获取应用列表时过滤掉…

Unity 之利用Audio Source(音频源)组件用于播放声音

文章目录 Unity中的Audio Source(音频源)是一个用于播放声音的组件,通常附加到游戏对象上,以便在游戏中播放音频效果、音乐或对话。以下是Audio Source的详细介绍: 添加Audio Source: 要在Unity中使用Audio…

Qt 5.15集成Crypto++ 8.8.0(MSVC 2019)笔记

一、背景 笔者已介绍过在Qt 5.15.x中使用MinGW(8.10版本)编译并集成Crypto 8.8.0。 但是该编译出来的库(.a和.dll)不适用MSVC(2019版本)构建环境,需要重新编译(.lib或和.dll&#xf…

索尼 toio™应用创意开发征文|toio俄罗斯方块游戏

目录 引言 摘要 创意简述 准备工作|手工开始 代码编写|合理集成 使用体验|近乎奇妙 引言 索尼toio™编程机器人是一款引领技术创新的产品,为开发者提供了一个全新的编程和创造平台。toio™的设计旨在将技术、塑性和乐趣融为…

机器学习实战-系列教程4:线性回归3(项目实战、原理解读、源码解读)

🌈🌈🌈机器学习 实战系列 总目录 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 机器学习实战-系列教程1:线性回归入门教程 机器学习实战-系列教程2:线性回归1 机器学习实战-系列教程3&am…

WMS仓储管理系统如何加强印刷企业仓库管理

在当今的数字化时代,仓库管理系统的智能化和信息化已经成为企业运营效率的重要支柱。印刷企业WMS仓储管理系统,作为一种先进的管理工具,正在被越来越多的印刷企业所采用,以加强他们的仓库管理工作。 一、WMS仓储管理系统概述 WMS…

Stable Doodle:简单涂鸦一键变成艺术品

摘要: Stable Doodle 是一款使用 AI 技术将简单涂鸦转化为艺术品的应用。它可以帮助用户快速、轻松地创作出精美的图画。本教程将介绍 Stable Doodle 的基本使用方法。 正文: Stable Doodle 的使用非常简单。只需以下几步即可: 打开 Stab…

2023数学建模国赛选题建议及BC题思路

大家好呀,全国大学生数学建模竞赛今天下午开赛啦,在这里先带来初步的选题建议及思路。 目前团队正在写B题和C题完整论文,后续还会持续更新哈,以下只是比较简略的图文版讲解,团队目前正在写B、C题完整论文,…

linux运维(二)内存占用分析

一、centos内存高,查看占用内存, top命令详解 1.1: free 命令是 free 单位K free -m 单位M free -h 单位Gfree最常规的查看内存占用情况的命令 1.2: 参数说明 total 总物理内存 used 已经使用的内存 free 没有使用的内存 shared 多进程共享内存 buff/cache 读写…

windows docker 容器启动报错:Ports are not available

docker 启动容器报错: (HTTP code 500) server error - Ports are not available: listen tcp 0.0.0.0:6379: bind: An attempt was made to access a socket in a way forbidden by its access permissions. 问题排查 检查端口是否被其它程序占用:nets…

git:一个本地仓库绑定多个远程的方法以及遇到的问题

绑定方法见知乎大佬:本地Git仓库关联多个远程仓库的两种方法 一般情况下,没人这么搞! 但是公司迁移git仓库阶段,xx云环境上的gitlab要有操作记录,不然影响整体评分,这就不得一个本地仓库关联了原来的仓库新…