MySQL数据库-存储过程详解

article/2025/11/5 22:29:09

存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批件,虽然它们的作用不仅限于批处理。在我看来, 存储过程就是有业务逻辑和流程的集合, 可以在存储过程中创建表,更新数据, 删除等等。

MySQL基础教程之存储过程

存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批件,虽然它们的作用不仅限于批处理。在我看来, 存储过程就是有业务逻辑和流程的集合, 可以在存储过程中创建表,更新数据, 删除等等。


为什么要使用存储过程

  1. 通过把处理封装在容易使用的单元中,简化复杂的操作(正如前面例子所述)。
  2. 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一(试验和测试)存储过程,则所使用的代码都是相同的。这一点的延伸就是防止错误。需要执行的步骤越多,出错的可能性就越大。防止错误保证了数据的一致性。
  3. 简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,只需要更改存储过程的代码。使用它的人员甚至不需要知道这些变化。

一个简单的存储过程

  
  1. create procedure porcedureName () 
  2. begin 
  3.     select name from user
  4. end 

存储过程用create procedure 创建, 业务逻辑和sql写在begin和end之间。mysql中可用call porcedureName ();来调用过程。

  
  1. -- 调用过程 
  2. call porcedureName ();  

该存储过程没有参数, 只是在调用的时候查询了用户表的用户名而已, 调用结果如下

name
admin
admin1
admin2
admin3

删除存储过程

  
  1. DROP PROCEDURE IF EXISTS porcedureName; -- 没有括号() 

在这里,我们还要了解三个特别的字段in,out以及inout的区别,那么我们可以从下面的例子去体会,然后再看详细的使用方式:

1.参数in的使用(代表输入,意思说你的参数要传到存过过程的过程里面去)
//为了避免存储过程中分号(";")结束语句,我们使用分隔符告诉mysql解释器,该段命令是否已经结束了。
/**
案例功能:求1-n的和
*/
delimiter $
create procedure p1(in n int)
begin
declare total int default 0;
declare num int default 0;
while num < n do
set num:=num+1;
set total:=total+num;
end while;
select total;
end$

call p1(10)$

创建并执行完存储过程,运行结果如下:

2.参数out的使用(代表往外输出)
//这里还要注意一点的就是我们的输出参数一定要设置相应类型的初始,否则不管你怎么计算得出的结果都为NULL值
/**
案例功能:求1-n的和
*/
create procedure p2(in n int,out total int)
begin
declare num int default 0;
set total:=0;
while num < n do
set num:=num+1;
set total:=total+num;
end while;
end$
注意:对于第一个输入参数我们可以理解,但是第二个输出参数我们到底应该怎么输?
这里我们需要对第二个参数定义一个变量名(更形象点就是你输入一个输入类型的参数n,由输出参数total往外发射输出我们只需要定义一个变量名来接收这个输出值即可)
call p2(100,@sum)$//这里的@sum就是我定义用来接收处处total的值
select @sum$
创建并执行完存储过程(查询定义的变量值),运行结果如下:

总结in、out区别:
in:表示输入一个值,你需要一个值,我给你一个值
out:你往外输出一个值,你输出的那个值我就拿一个变量来接收你给我输出的那个值

3.参数inout的使用(既能输入一个值又能传出来一个值)
/**
功能:传一个年龄,自动让年龄增长10岁
*/
create procedure p3(inout age int)
begin
set age:=age+10;
end$
注意:调用的时候,我这里需要和大家声明一下,inout型的参数值既是输入类型又是输出类型,你给它一个值,值不是变量,不是变量那out的时候它怎么赋给这个值是不是?
因此我们需要先设置一个变量并初始化这个值,调用的时候直接传这个变量即可。
set @currentAge=8$
call p3(@currentAge)$
select @currentAge$
创建并执行完存储过程,运行结果如下:



使用参数的存储过程(备注:decimal(8,2)意思就是总共有8位,小数点后留两位

 
  1. create procedure procedureName( 
  2.     out min decimal(8,2), 
  3.     out avg decimal(8,2), 
  4.     out max decimal(8,2) 
  5. BEGIN 
  6.     select MIN(price) INTO min from order
  7.     select AVG(price) into avg from order
  8.     select MAX(price) into max from order
  9. END 

此过程接受三个参数, 分别用于获取订单表的最小、平均、最大价格。每个参数必须具有指定的类

型,这里使用十进制值(decimal(8,2)), 关键字OUT指出相应的参数用来从存储过程传出

一个值(返回给调用者)

MySQL支持IN(传递给存储过程)、OUT(从存储过程传出,如这里所用)和INOUT(对存储过程传入和传出)类型的参数。存储过程的代码位于BEGIN和END语句内,如前所见,它们是一系列SELECT语句,用来检索值,然后保存到相应的变量(通过指定INTO关键字)

为调用此修改过的存储过程,必须指定3个变量名,如下所示:(所有MySQL变量都必须以@开始。)

 
  1. -- 由于过程指定三个参数, 故调用必须要参数匹配 
  2. call procedureName(@min, @avg, @max);  

该调用并没有任何输出, 只是把调用的结果赋给了调用时传入的变量(@min, @avg, @max)。然后即可调用显示该变量的值。

 
  1. select @min, @avg, @max

结果如下

@min @avg @max
42.00 601.00 2222.00

使用in参数, 输入一个用户id, 返回该用户所有订单的总价格。

 
  1. create procedure getTotalById ( 
  2.     in userId int
  3.     out total decimal(8,2) 
  4. BEGIN 
  5.     select SUM(r.price) from order r 
  6.     where r.u_id = userId 
  7.     into total; 
  8. END 

调用存储过程

 
  1. call getTotalById(1, @total); 
  2. select @total;  

结果将返回该用户所有订单的合计价格。

复杂一点的过程, 根据用户id获取该用户的所有订单价格, 并动态的选择是否加税。代码设计如下

 
  1. create procedure getTotalByUser2( 
  2.     in userId int
  3.     in flag boolean, -- 是否加税标记 
  4.     out total decimal(8,2) 
  5. begin 
  6.     DECLARE tmptotal DECIMAL(8,2); 
  7.     DECLARE taxrate int DEFAULT 6;-- 默认的加税的利率 
  8.      
  9.     select SUM(r.price) from order r 
  10.     where r.u_id = userId 
  11.     into tmptotal; 
  12.      
  13.     if flag then 
  14.         select tmptotal + (tmptotal/1000*taxrate) into tmptotal; 
  15.     end if; 
  16.      
  17.     select tmptotal into total; 
  18. END 

该过程传入三个参数, 用户id, 是否加税以及返回的总价格,在过程内部, 定义两个局部变量tmptotal和taxrate,把查询出来的结果赋给临时变量, 在判断是否加税。最后把局部变量的值赋给输出参数。

 
  1. call getTotalByUser2(1, false, @total); -- 不加税 
  2. call getTotalByUser2(1, true, @total);  -- 加税 
  3. select @total; 



http://chatgpt.dhexx.cn/article/oa8a8YJP.shtml

相关文章

EXTJS5 入门指南

EXTJS5带领EXTJS步入了新的时代&#xff0c;Ext JS 5已经不再支持IE6、IE7和其他旧版本的浏览器了&#xff0c;这样可以显著减少跨整个框架的逻辑和样式设置。再加上额外的优化&#xff0c;Ext JS 5已经为企业级的Web应用程序迈出了惊人的一步。 EXTJS5不在和EXTJS4一样&#x…

ExtJS-入门(转载自http://www.blogjava.net/puras/archive)

2010 - 01 - 13 缩略显示 ExtJS-入门&#xff08;转载自http://www.blogjava.net/puras/archive&#xff09; 文章分类:Web前端 在ExtJS里最常用的,应该就是Ext.onReady这个方法了, 而且它也可能是你学习ExtJS所接触的第一个方法,这个方法在当前的DOM加载完毕后自动调用,保证…

Ext JS 6学习文档–第1章–ExtJS入门指南

Ext JS 入门指南 前言 本来我是打算自己写一个系列的 ExtJS 6 学习笔记的&#xff0c;因为 ExtJS 6 目前的中文学习资料还很少。google 搜索资料时找到了一本国外牛人写的关于 ExtJS 6 的电子书 [Ext JS 6 By Example]。这份资料在 PACKT 上卖 35.99 刀的&#xff0c;当然了万…

Extjs——初步学习

最近在系统学习Extjs框架&#xff0c;从刚一开始接触Extjs到现在发现对Extjs越来越喜欢了。刚开始只是想在页面上实现一个展示大量图片的功能&#xff0c;就像在线订餐系统展示菜单的效果那样&#xff0c;每幅图片上都有一些必要的信息、动作、链接等。效果如下图&#xff1a; …

Extjs基础(一)

1.1基础学习 说明&#xff1a; 本示例的所有代码均在extjs6.2版本上测试通过,学习内容来源于官方文档和自己的一些见解。 1.1.1window组件 简单的一个window面板&#xff1a; title: 窗口标题,height: 220, //可以使用百分比width: 220, html: 内容部分,resizable: true, //…

ExtJS基础入门

公司需要用ExtJS搭建系统框架&#xff0c;然后&#xff0c;这个很老了&#xff0c;没有用过 。 开始进行时候一脸懵逼&#xff0c;因为搜索了相关的知识&#xff0c;面临如下问题&#xff1a; 1.版本太多&#xff0c;从一到六&#xff0c;不知从何入手 2.提供的教程和视频都…

extjs初学者教程

layout 1.面板 (1)类结构 Ext.Base Ext.AbstractComponent Ext.Component Ext.container.AbstractContainer Ext.container.Container Ext.panel.AbstractPanel …

ext.js入门

序言&#xff1a;extjs 是一种OOP语言&#xff0c;可以按照学习Java 的过程来进行学习&#xff0c;可以类比 Java中的图像界面JWT来进行学习。 工具 这些是sencha提供的用于Ext JS应用程序开发的工具&#xff0c;主要用于生产级别。Sencha Cmd Sencha CMD是一个提供Ext JS代码…

EXTJS入门教程及其框架搭建

EXTJS是一个兼容AJAX的前台WEB UI的框架&#xff0c;在普通的HTML文件的 BODY 元素中无须写任何HTML代码&#xff0c;就能产生相应的表格等元素。 原创不易&#xff0c;转载请注明出处&#xff1a;EXTJS入门教程及其框架搭建 代码下载地址:http://www.zuidaima.com/share/17244…

EXTJS详细教程

布局和容器 普通布局 Ext.create(Ext.panel.Panel, {renderTo: Ext.getBody(),width: 400,height: 300,title: Container Panel,items: [{xtype: panel,title: Child Panel 1,height: 100,width: 75%}, {xtype: panel,title: Child Panel 2,height: 100,width: 75%}] });列布…

国嵌视频,买了就是坑

国嵌买视频的&#xff0c;更新慢&#xff0c;谁敢抱怨&#xff0c;踢你&#xff0c;锁你账号&#xff0c;真无语&#xff0c;安卓没录完&#xff0c;3月拖到6月&#xff0c;拖到10月&#xff0c;引起公愤了&#xff0c;就说送路由视频&#xff0c;结果路由视频还没录呢&#xf…

【我爱嵌入式】

童鞋们 自动化嵌入式复习 总结了期末考试简答题的内容 第一章 嵌入式的定义 以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软硬件可裁剪&#xff0c;对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。嵌入式系统主要由嵌入式微处理器、外围硬件设备…

嵌入式教程:什么是嵌入式?

每每有小白接触嵌入式时&#xff0c;总认为是装修风格的一种&#xff0c;类似嵌入式壁炉之类的&#xff0c;而一些有过了 解的朋友可能会以为嵌入式教程就是教单片机的&#xff0c;学习后才发现单片机只是基础。 简单来说&#xff0c;嵌入式就是需要嵌入某些东西里面&#xff…

国嵌视频学习笔记---linux内核开发1

一、linux内核简介 1.linux系统由两部分组成&#xff1a;内核空间和用户空间。 2.用户空间包括&#xff1a;用户应用程序和C库 3.内核空间包括&#xff1a;系统调用接口、内核和体系结构相关代码。 4.ARM处理器7种工作模式&#xff1a;用户模式&#xff0c;快速中断模式、外…

国嵌学习——ARM

从NOR启动&#xff1a;在片选0位置放置的是2M的nor flash&#xff0c;在片选6位置放置的是内存0x30000000 ARM工作模式 ARM处理器的运行模式可以通过软件改变&#xff0c;也可以通过外部中断或异常处理改变。应用程序运行在用户模式下&#xff0c;当处理器运行在用户模式下时&…

国嵌C语言(6-10)

国嵌六&#xff1a; 空结构体的内存&#xff1a; struct D {}; int main(void) {struct D d1;struct D d2;printf("%d\n",sizeof(struct D));printf("%d,%0x\n",sizeof(d1),&d1);printf("%d,%0x\n",sizeof(d2),&d2); } 0 0&#xff…

【嵌入式】

一.进制转换&#xff1a;分别有以下前缀&#xff0c;2进制常用0B表示&#xff0c;8进制常用0O&#xff0c;16进制常用0X表示&#xff1b;1位八进制数等于3位二进制数&#xff0c;1位十六进制数等于4位二进制数&#xff0c;在二进制转化为八&#xff0c;十六进制数时。如果位数不…

关于嵌入式系统

说实话&#xff0c;笔者是对嵌入式有兴趣的&#xff0c;为什么&#xff0c;因为对于我这样的懒人&#xff0c;是希望以后出去找个稳定的工作&#xff0c;随着年龄的增长工资越高&#xff0c;经验越多&#xff0c;就越吃香&#xff0c;而不是当个最底层的码农&#xff0c;35岁之…

国嵌,够欠!---ARM在线教育误区

大家好&#xff0c;先自我介绍一下&#xff0c;我是国嵌学院的一个很普通的学员&#xff0c;因为应届生不好找工作&#xff0c;去培训机构培训又和上课时间冲突&#xff0c;所以选择了自主学习。在机缘巧合之下&#xff0c;购买了国嵌学院的嵌入式Linux开发课程&#xff0c;在此…

国嵌C语言总结(1-5)

国嵌一&#xff1a; 什么是数据类型&#xff1f; 数据类型是固定内存大小的别名&#xff0c;是创建变量的模子&#xff1b; 变量的本质&#xff1f; 变量是一段实际连续存储空间的别名&#xff1b;程序通过变量来申请并命名存储空间&#xff1b;通过变量的名字可以使用存储空…