MySQL中的存储过程(详细篇)

article/2025/10/3 15:21:38

文章目录

  • 概述
    • 优点
    • 缺点
  • MySQL存储过程的定义
    • 存储过程的基本语句格式
    • 存储过程的使用
      • 定义一个存储过程
      • 定义一个有参数的存储过程
      • 定义一个流程控制语句 IF ELSE
      • 定义一个条件控制语句 CASE
      • 定义一个循环语句 WHILE
      • 定义一个循环语句 REPEAT UNTLL
      • 定义一个循环语句 LOOP
      • 使用存储过程插入信息
    • 存储过程的管理
      • 显示存储过程
      • 显示特定数据库的存储过程
      • 显示特定模式的存储过程
      • 显示存储过程的源码
      • 删除存储过程
  • 后端调用存储过程的实现

在这里插入图片描述

概述

由MySQL5.0 版本开始支持存储过程。

如果在实现用户的某些需求时,需要编写一组复杂的SQL语句才能实现的时候,那么我们就可以将这组复杂的SQL语句集提前编写在数据库中,由JDBC调用来执行这组SQL语句。把编写在数据库中的SQL语句集称为存储过程。

存储过程:(PROCEDURE)是事先经过编译并存储在数据库中的一段SQL语句的集合。调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是很有好处的。

就是数据库 SQL 语言层面的代码封装与重用。

存储过程就类似于Java中的方法,需要先定义,使用时需要调用。存储过程可以定义参数,参数分为IN、OUT、INOUT类型三种类型。

  1. IN类型的参数表示接受调用者传入的数据;
  2. OUT类型的参数表示向调用者返回数据;
  3. INOUT类型的参数即可以接受调用者传入的参数,也可以向调用者返回数据。

优点

  1. 存储过程是通过处理封装在容易使用的单元中,简化了复杂的操作。

  2. 简化对变动的管理。如果表名、列名、或业务逻辑有了变化。只需要更改存储过程的代码。使用它的人不用更改自己的代码。

  3. 通常存储过程都是有助于提高应用程序的性能。当创建的存储过程被编译之后,就存储在数据库中。
    但是,MySQL实现的存储过程略有所不同。
    MySQL存储过程是按需编译。在编译存储过程之后,MySQL将其放入缓存中。
    MySQL为每个连接维护自己的存储过程高速缓存。如果应用程序在单个连接中多次使用存储过程,则使用编译版本,否则存储过程的工作方式类似于查询。

  4. 存储过程有助于减少应用程序和数据库服务器之间的流量。
    因为应运程序不必发送多个冗长的SQL语句,只用发送存储过程中的名称和参数即可。

  5. 存储过程度任何应用程序都是可重用的和透明的。存储过程将数据库接口暴露给所有的应用程序,以方便开发人员不必开发存储过程中已支持的功能。

  6. 存储的程序是安全的。数据库管理员是可以向访问数据库中存储过程的应用程序授予适当的权限,而不是向基础数据库表提供任何权限。

缺点

  1. 如果使用大量的存储过程,那么使用这些存储过程的每个连接的内存使用量将大大增加。
    此外,如果在存储过程中过度使用大量的逻辑操作,那么CPU的使用率也在增加,因为MySQL数据库最初的设计就侧重于高效的查询,而不是逻辑运算。

  2. 存储过程的构造使得开发具有了复杂的业务逻辑的存储过程变得困难。

  3. 很难调试存储过程。只有少数数据库管理系统允许调试存储过程。不幸的是,MySQL不提供调试存储过程的功能。

  4. 开发和维护存储过程都不容易。
    开发和维护存储过程通常需要一个不是所有应用程序开发人员拥有的专业技能。这可能导致应用程序开发和维护阶段的问题。

  5. 对数据库依赖程度较高,移值性差。

MySQL存储过程的定义

存储过程的基本语句格式

DELIMITER $$CREATE/*[DEFINER = { user | CURRENT_USER }]*/PROCEDURE 数据库名.存储过程名([in变量名 类型,out 参数 2...])/*LANGUAGE SQL| [NOT] DETERMINISTIC| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }| SQL SECURITY { DEFINER | INVOKER }| COMMENT 'string'*/BEGIN[DECLARE 变量名 类型 [DEFAULT];]存储过程的语句块;END$$DELIMITER ;

● 存储过程中的参数分别是 in,out,inout三种类型;

  1. in代表输入参数(默认情况下为in参数),表示该参数的值必须由调用程序指定。
  2. ou代表输出参数,表示该参数的值经存储过程计算后,将out参数的计算结果返回给调用程序。
  3. inout代表即时输入参数,又是输出参数,表示该参数的值即可有调用程序制定,又可以将inout参数的计算结果返回给调用程序。

● 存储过程中的语句必须包含在BEGIN和END之间。

● DECLARE中用来声明变量,变量默认赋值使用的DEFAULT,语句块中改变变量值,使用SET 变量=值;

存储过程的使用

定义一个存储过程

DELIMITER $$CREATEPROCEDURE `demo`.`demo1`()-- 存储过程体BEGIN-- DECLARE声明 用来声明变量的DECLARE de_name VARCHAR(10) DEFAULT '';SET de_name = "jim";-- 测试输出语句(不同的数据库,测试语句都不太一样。SELECT de_name;END$$DELIMITER ;

在这里插入图片描述

调用存储过程

CALL demo1();

在这里插入图片描述

定义一个有参数的存储过程

先定义一个student数据库表:
在这里插入图片描述

现在要查询这个student表中的sex为男的有多少个人。

DELIMITER $$CREATEPROCEDURE `demo`.`demo2`(IN s_sex CHAR(1),OUT s_count INT)-- 存储过程体BEGIN-- 把SQL中查询的结果通过INTO赋给变量SELECT COUNT(*) INTO s_count FROM student WHERE sex= s_sex;SELECT s_count;END$$
DELIMITER ;

调用这个存储过程

-- @s_count表示测试出输出的参数
CALL demo2 ('男',@s_count);

在这里插入图片描述

定义一个流程控制语句 IF ELSE

IF 语句包含多个条件判断,根据结果为 TRUE、FALSE执行语句,与编程语言中的 if、else if、else 语法类似。

DELIMITER $$
CREATEPROCEDURE `demo`.`demo3`(IN `day` INT)-- 存储过程体BEGINIF `day` = 0 THENSELECT '星期天';ELSEIF `day` = 1 THENSELECT '星期一';ELSEIF `day` = 2 THENSELECT '星期二';ELSESELECT '无效日期';END IF;END$$
DELIMITER ;

调用这个存储过程

CALL demo3(2);

在这里插入图片描述

定义一个条件控制语句 CASE

case是另一个条件判断的语句,类似于编程语言中的 choose、when语法。MySQL 中的 case语句有两种语法格式。

  1. 第一种
DELIMITER $$
CREATE PROCEDURE demo4(IN num INT)BEGINCASE -- 条件开始WHEN num<0 THEN SELECT '负数';WHEN num>0 THEN SELECT '正数';ELSE SELECT '不是正数也不是负数';END CASE; -- 条件结束END$$
DELIMITER;

调用这个存储过程

CALL demo4(1);

在这里插入图片描述

2.第二种

DELIMITER $$
CREATE PROCEDURE demo5(IN num INT)BEGINCASE num  -- 条件开始WHEN 1 THEN SELECT '输入为1';WHEN 0 THEN SELECT '输入为0';ELSE SELECT '不是1也不是0';END CASE; -- 条件结束END$$
DELIMITER;

调用此函数

CALL demo5(0);

在这里插入图片描述

定义一个循环语句 WHILE

DELIMITER $$
CREATE PROCEDURE demo6(IN num INT,OUT SUM INT)BEGINSET SUM = 0;WHILE num<10 DO -- 循环开始SET num = num+1;SET SUM = SUM+num;END WHILE; -- 循环结束END$$
DELIMITER;

调用此函数

-- 调用函数
CALL demo6(0,@sum);-- 查询函数
SELECT @sum;

在这里插入图片描述

定义一个循环语句 REPEAT UNTLL

REPEATE…UNTLL 语句的用法和 Java中的 do…while 语句类似,都是先执行循环操作,再判断条件,区别是REPEATE 表达式值为 false时才执行循环操作,直到表达式值为 true停止。

-- 创建过程
DELIMITER $$
CREATE PROCEDURE demo7(IN num INT,OUT SUM INT)BEGINSET SUM = 0;REPEAT-- 循环开始SET num = num+1;SET SUM = SUM+num ;UNTIL num>=10END REPEAT; -- 循环结束END$$
DELIMITER;

调用此函数

CALL demo7(9,@sum);SELECT @sum;

在这里插入图片描述

定义一个循环语句 LOOP

循环语句,用来重复执行某些语句。

执行过程中可使用 LEAVE语句或者ITEREATE来跳出循环,也可以嵌套IF等判断语句。

  1. LEAVE 语句效果对于Java中的break,用来终止循环;
  2. ITERATE语句效果相当于Java中的continue,用来跳过此次循环。进入下一次循环。且ITERATE之下的语句将不在进行。
DELIMITER $$
CREATE PROCEDURE demo8(IN num INT,OUT SUM INT)BEGINSET SUM = 0;demo_sum:LOOP-- 循环开始SET num = num+1;IF num > 10 THENLEAVE demo_sum; -- 结束此次循环ELSEIF num <= 9 THENITERATE demo_sum; -- 跳过此次循环END IF;SET SUM = SUM+num;END LOOP demo_sum; -- 循环结束END$$
DELIMITER;

调用此函数

CALL demo8(0,@sum);SELECT @sum;

在这里插入图片描述

使用存储过程插入信息

DELIMITER $$
CREATE PROCEDURE demo9(IN s_student VARCHAR(10),IN s_sex CHAR(1),OUT s_result VARCHAR(20))BEGIN-- 声明一个变量 用来决定这个名字是否已经存在DECLARE s_count INT DEFAULT 0;-- 验证这么名字是否已经存在SELECT COUNT(*) INTO s_count FROM student WHERE `name` = s_student;	IF s_count = 0 THENINSERT INTO student (`name`, sex) VALUES(s_student, s_sex);SET s_result = '数据添加成功';ELSESET s_result = '名字已存在,不能添加';SELECT s_result;END IF;END$$
DELIMITER;

调用此函数

CALL demo9("Jim","女",@s_result);

在这里插入图片描述

再次调用次函数

CALL demo9("Jim","女",@s_result)

在这里插入图片描述

存储过程的管理

显示存储过程

SHOW PROCEDURE STATUS

在这里插入图片描述

显示特定数据库的存储过程

SHOW PROCEDURE STATUS WHERE db = 'db名字' AND NAME = 'name名字';

显示特定模式的存储过程

SHOW PROCEDURE STATUS WHERE NAME LIKE '%mo%';

在这里插入图片描述

显示存储过程的源码

SHOW CREATE PROCEDURE 存储过程名;

在这里插入图片描述

删除存储过程

DROP PROCEDURE 存储过程名;

后端调用存储过程的实现

在mybatis当中,调用存储过程

<parameterMap type="savemap" id=“usermap"> <parameter property="name" jdbcType="VARCHAR" mode="IN"/><parameter property="sex" jdbcType="CHAR" mode="IN"/><parameter property="result" jdbcType="VARCHAR" mode="OUT"/>
</parameterMap><insert id="saveUserDemo" parameterMap="savemap" statementType="CALLABLE"> 
{call saveuser(?, ?, ?)} 
</insert >

调用数据库管理

HashMap<String, Object> map = new HashMap<String, Object>(); map.put("name", "Jim"); map.put("sex","男");userDao.saveUserDemo(map); map.get(“result”);//获得输出参数

通过这样就可以调用数据库中的存储过程的结果。


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

相关文章

跨域及cors解决跨域

1.什么是跨域 出于浏览器的同源策略限制。同源策略&#xff08;Sameoriginpolicy&#xff09;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;如果缺少了同源策略&#xff0c;则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的…

什么是跨域?如何解决跨域?

✨ 目录 &#x1f388; 什么是跨域&#x1f388; 跨域场景&#x1f388; 解决跨域的四种方式 &#x1f388; 什么是跨域 域&#xff1a; 是指浏览器不能执行其他网站的脚本跨域&#xff1a; 它是由浏览器的 同源策略 造成的,是浏览器对 JavaScript 实施的安全限制&#xff0c;…

关于跨域后端解决跨域问题

一、为什么会有跨域 出于浏览器的同源策略限制。**同源策略&#xff08;Sameoriginpolicy&#xff09;**是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;如果缺少了同源策略&#xff0c;则浏览器的正常功能可能都会受到影响。同源策略会阻止一个域的ja…

什么是跨域?跨域问题怎么解决?

目录 一、什么是跨域&#xff1f; 二、为什么会出现跨域问题&#xff1f; 三、常见的跨域场景 四、跨域解决方法 1、JSONP &#xff08;1&#xff09;JSONP原理 &#xff08;2&#xff09;JSONP和AJAX对比 &#xff08;3&#xff09;JSONP优缺点 &#xff08;4&#x…

跨域的本质

简介 相信大家在做web系统开发的时候&#xff0c;都遇到过前端页面访问另一个服务器而非本服务器从而遭遇的跨域问题。跨域是个很常见的问题&#xff0c;虽然在web系统中的解决方式很简单&#xff0c;加一段耳熟能详的代码&#xff0c;或者一个注解&#xff0c;或者在某个框架中…

跨域及解决

文章目录 什么是跨域&#xff1f;Origin同源的例子不同源的例子为什么需要跨域&#xff1f;请求跨域了&#xff0c;那么请求到底发出去没有&#xff1f; 如何解决&#xff1f;1.JSONP2.corsa.简单请求b.复杂请求 3.postMessage4.websocket5.nginx6.document.domain Iframe cli…

什么是跨域?以及解决跨域的方法?

【学习什么是跨域&#xff0c;以及如何解决跨域。】 1、什么是跨域&#xff1f;&#xff08;什么是同源策略&#xff1f;&#xff09; 跨域&#xff1a; 由于浏览器的同源策略引起的&#xff0c;如果说协议、域名、端口号有任何一个不一样&#xff0c;都会引起跨域 为什么会出…

【跨域】Java后端解决跨域问题

废话不多说&#xff0c;先上完整代码 建corsConfig文件&#xff0c;copy下面内容&#xff0c;放进去 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfigur…

什么是同源策略,什么是跨域,如何解决跨域

1.什么是同源策略&#xff1f; 同源策略/SOP&#xff08;Same origin policy&#xff09;是一种约定&#xff0c;由 Netscape 公司 1995 年引入浏览器&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;现在所有支持 JavaScript 的浏览器都会使用这个策略。如果缺少…

前端解决跨域----代理跨域

跨域报错&#xff1a; CORS error 为什么会跨域 ​ 先了解跨域的概念&#xff1a;发送请求的url的协议、域名、端口三者之间任意一个与当前页面的地址不同则视为跨域。 解决跨域 vue.config.js 设置代理跨域 module.exports {devServer: {proxy: {/api: {target: "ht…

什么是跨域问题?跨域解决问题

一.为什么会出现跨域问题? 出于浏览器的同源策略限制.同源策略是一种约定,它是浏览器最核心也是最基本的安全功能,如果缺少了同源策略,则浏览器的正常的功能可能会受到影响,跨域收是Web是构建在同源策略基础上的,浏览器只是针对同源策略的一种实现,同源策略会阻止一个域的Jav…

什么是跨域及怎么解决跨域问题?

什么是跨域&#xff1f; 这篇博文解释的挺清楚&#xff0c;我直接引用 什么是跨域&#xff1f;怎么解决跨域问题&#xff1f;_L瑜-CSDN博客_跨域是什么意思 跨域&#xff0c;指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的&#xff0c;是浏览器施加的安全…

VUE跨域、常用解决跨域的方法

当我们遇到请求后台接口遇到 Access-Control-Allow-Origin 时&#xff0c;那说明跨域了。 跨域是因为浏览器的同源策略所导致&#xff0c;同源策略&#xff08;Same origin policy&#xff09;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能&#xff0c;同源是指&…

什么是跨域?怎么解决跨域问题

文章目录 一、同源策略二、同源策略案例三、什么是跨域四、跨域解决方法1.ajax的jsonp概念核心用法 2.CORS方式3.nginx 转发 一、同源策略 同源策略&#xff0c;是由 Netscape 提出的一个安全策略&#xff0c;它是浏览器最核心也是最基本的安全功能&#xff0c;如果缺少同源策…

什么是跨域以及为什么会出现跨域以及跨域的解决方案

1.什么是跨域&#xff1f; 跨域&#xff1a;指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的&#xff0c;是浏览器对javascript施加的安全限制。 • 同源策略&#xff1a;是指协议&#xff0c;域名&#xff0c;端口都要相同&#xff0c;其中有一个不同都会产…

什么是跨域?如何解决?

一、什么是跨域&#xff1f; 跨域&#xff1a;指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的&#xff0c;是浏览器对javascript施加的安全限制。 例如&#xff1a;a页面想获取b页面资源&#xff0c;如果a、b页面的协议、域名、端口、子域名不同&#xf…

什么是跨域? 出现原因及解决方法

目录 一、什么是跨域二、为什么有跨域问题&#xff1f;三、解决跨域问题的方案1.Jsonp2.nginx3.CORS3.1 什么是cors3.2 原理 四、GateWay网关中实现跨域步骤 一、什么是跨域 跨域&#xff1a;浏览器对于javascript的同源策略的限制 。 同源政策的目的&#xff0c;是为了保证用…

什么是跨域及解决跨域都有哪些方法?

一.同源策略 浏览器为了隔离潜在的恶意文件&#xff0c;使用同源策略&#xff0c;限制从一个源加载的文档或脚本和另一个源的资源进行交互&#xff08;不同源之间的文档&#xff0c;资源的交互&#xff09;; 通俗的理解&#xff1a;浏览器规定&#xff0c;A 网站的 JavaScript…

什么是跨域,怎么解决跨域?

1.什么是跨域 跨域是指浏览器不能执行其他网站的脚本。它是浏览器同源策略造成的&#xff0c;是浏览器对JS实施的安全限制。 2.常见的跨域场景 3.什么是同源策略&#xff1f; &#xff08;所谓同源是指&#xff1a;“域名”、“协议”、“端口”均为相同&#xff09; 同源策略/…

最常见的六种跨域解决方案

目录&#xff1a; 前言&#xff1a;什么是跨域&#xff1f;JSONPCORS搭建Node代理服务器Nginx反向代理postMessageWebsocket总结 前言&#xff1a;什么是跨域&#xff1f; 跨域就是当在页面上发送ajax请求时&#xff0c;由于浏览器同源策略的限制&#xff0c;要求当前页面和…