MySQL创建存储过程和存储函数

【图书推荐】《MySQL 9从入门到性能优化(视频教学版)》-CSDN博客


《MySQL 9从入门到性能优化(视频教学版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com)

MySQL9数据库技术_夏天又到了的博客-CSDN博客

存储程序可以分为存储过程和函数。在MySQL中,创建存储过程和存储函数使用的语句分别是CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句来调用存储过程,只能用输出变量返回值。存储函数可以从语句外调用(引用函数名),也能返回标量值。一个存储过程可以调用其他存储过程。

8.1.1  创建存储过程

创建存储过程,需要使用CREATE PROCEDURE语句,基本语法格式如下:

CREATE PROCEDURE sp_name ( [proc_parameter] )

[characteristics ...] routine_body

各参数解释如下:

(1)CREATE PROCEDURE为用来创建存储过程的关键字。

(2)sp_name为存储过程的名称。

(3)proc_parameter为指定存储过程的参数列表,列表形式如下:

[ IN | OUT | INOUT ] param_name type

其中,IN表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出;param_name表示参数名称;type表示参数的类型,该类型可以是MySQL数据库中的任意类型。

(4)characteristics指定存储过程的特性,有以下取值:

  • LANGUAGE SQL:说明routine_body部分是由SQL语句组成的,当前系统支持的语言为SQL。SQL是LANGUAGE特性的唯一值。
  • [NOT] DETERMINISTIC:指明存储过程执行的结果是否确定。DETERMINISTIC表示结果是确定的,每次执行存储过程时,相同的输入会得到相同的输出;NOT DETERMINISTIC表示结果是不确定的,相同的输入可能得到不同的输出。如果没有指定值,则默认为NOT DETERMINISTIC。
  • { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:指明子程序使用SQL语句的限制。CONTAINS SQL表明子程序包含SQL语句,但是不包含读写数据的语句;NO SQL表明子程序不包含SQL语句;READS SQL DATA说明子程序包含读数据的语句;MODIFIES SQL DATA表明子程序包含写数据的语句。默认情况下,系统会指定为CONTAINS SQL。
  • SQL SECURITY { DEFINER | INVOKER }:指明谁有权限来执行。DEFINER表示只有定义者才能执行;INVOKER表示拥有权限的调用者可以执行。默认情况下,系统指定为DEFINER。
  • COMMENT 'string':注释信息,可以用来描述存储过程或存储函数。

(5)routine_body是SQL代码的内容,可以用BEGIN…END来表示SQL代码的开始和结束。

编写存储过程并不是一件简单的事情,可能需要复杂的SQL语句,并且要有创建存储过程的权限。但是,使用存储过程将简化操作,减少冗余的操作步骤;同时,还可以减少操作过程中的失误,提高效率。因此,存储过程是非常有用的,而且应该尽可能地学会使用。

下面的代码演示了一个存储过程的创建,其名称为“AvgFruitPrice”,返回所有水果的平均价格:

CREATE PROCEDURE AvgFruitPrice ()
BEGIN
SELECT AVG(f_price) AS avgprice
FROM fruits;
END;

上述代码中,名为“AvgFruitPrice”的存储过程使用CREATE PROCEDURE AvgFruitPrice ()语句定义。此存储过程没有参数,但是后面的()仍然需要。BEGIN和END语句用来限定存储过程体,过程本身仅是一个简单的SELECT语句(AVG()为求字段平均值的函数)。

【例8.1】创建查看表fruits的存储过程,SQL语句如下:

CREATE PROCEDURE Proc()
     BEGIN
        SELECT * FROM fruits;
     END ;

上述代码创建了一个查看表fruits的存储过程,每次调用这个存储过程的时候都会执行SELECT语句查看表的内容,代码的执行过程如下:

MySQL> DELIMITER //
MySQL> CREATE PROCEDURE Proc()
    -> BEGIN
    -> SELECT * FROM fruits;
    -> END //
Query OK, 0 rows affected (0.00 sec)

MySQL> DELIMITER ;

这个存储过程和使用SELECT语句查看表的效果得到的结果是一样的。

当然,存储过程也可以是很多复杂语句的组合,其本身也可以调用其他的函数来组成更加复杂的操作。

【例8.2】创建名称为“CountProc”的存储过程,SQL语句如下:

CREATE PROCEDURE CountProc (OUT param1 INT)
BEGIN
SELECT COUNT(*) INTO param1 FROM fruits;
END;

上述代码的作用是创建一个获取表fruits中的记录条数的存储过程,其名称是CountProc;COUNT(*)计算后把结果放入参数param1中。执行结果如下:

mysql> DELIMITER // 
mysql> CREATE PROCEDURE CountProc(OUT param1 INT)
 -> BEGIN
 -> SELECT COUNT(*) INTO param1 FROM fruits;
 -> END;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;

8.1.2  创建存储函数

创建存储函数,需要使用CREATE FUNCTION语句,基本语法格式如下:

CREATE FUNCTION func_name ( [func_parameter] )

 RETURNS type

[characteristic ...] routine_body

各参数解释如下:

(1)CREATE FUNCTION为用来创建存储函数的关键字。

(2)func_name表示存储函数的名称

(3)func_parameter为存储过程的参数列表,参数列表形式如下:

[ IN | OUT | INOUT ] param_name type

其中,IN表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出;param_name表示参数名称;type表示参数的类型,该类型可以是MySQL数据库中的任意类型。

(4)RETURNS type语句表示函数返回数据的类型。

(5)characteristic指定存储函数的特性,取值与创建存储过程时的相同,这里不再赘述。

【例8.3】创建存储函数,名称为NameByZip,该函数返回SELECT语句的查询结果,数值类型为字符串型,SQL语句如下:

CREATE FUNCTION NameByZip ()

 RETURNS CHAR(50)

 RETURN  (SELECT s_name FROM suppliers WHERE s_call= '48075');

上述语句创建了一个存储函数NameByZip(),参数定义为空,返回一个CHAR类型的结果。代码的执行结果如下:

mysql> set global log_bin_trust_function_creators=TRUE;
mysql> DELIMITER //
mysql> CREATE FUNCTION NameByZip()
-> RETURNS CHAR(50)
-> RETURN   (SELECT s_name FROM suppliers WHERE s_call= '48075');
-> //

mysql> DELIMITER ;

如果存储函数中的RETURN语句返回一个类型不同于函数的RETURNS子句中的指定类型的值,则返回值将被强制为恰当的类型。例如,如果一个函数返回一个ENUM或SET值,但是RETURN语句返回一个整数,则对于SET成员集相应的ENUM成员,MySQL会将从函数返回的整数值转换为字符串。

8.1.5  光标的使用

查询语句可能返回多条记录,如果数据量非常大,则需要在存储过程和存储函数中使用光标来逐条读取查询结果集中的记录。应用程序可以根据需要滚动或浏览其中的数据。本小节将介绍如何声明、打开、使用和关闭光标。

光标必须在声明处理程序之前被声明,并且变量和条件还必须在声明光标或处理程序之前被声明。

1. 声明光标

在MySQL中,使用DECLARE关键字来声明光标,其语法的基本形式如下:

DECLARE cursor_name CURSOR FOR select_statement

其中,cursor_name参数表示光标的名称;select_statement参数表示SELECT语句的内容,返回一个用于创建光标的结果集。

【例8.10】声明名称为“cursor_fruit”的光标,SQL语句如下:

DECLARE cursor_fruit CURSOR FOR SELECT f_name, f_price FROM fruits ;

在本例中,光标的名称为“cur_fruit”,SELECT语句部分从表fruits中查询出f_name和f_price字段的值。

2. 打开光标

打开光标的语法如下:

OPEN cursor_name{光标名称}

【例8.11】打开名称为“cursor_fruit”的光标,SQL语句如下:

OPEN  cursor_fruit ;

3. 使用光标

使用光标的语法如下:

FETCH cursor_name INTO var_name [, var_name] ...{参数名称}

其中,cursor_name参数表示光标的名称;var_name参数表示将光标中的SELECT语句查询出来的信息存入该参数中,var_name必须在声明光标之前就已经定义好。

【例8.12】使用名称为“cursor_fruit”的光标将查询出来的数据存入fruit_name和fruit_price这两个变量中,SQL语句如下:

FETCH  cursor_fruit INTO fruit_name, fruit_price ;

在本例中,将光标cursor_fruit中用SELECT语句查询出来的信息存入fruit_name和fruit_price中,并且fruit_name和fruit_price必须在前面已经定义好。

4. 关闭光标

关闭光标的语法如下:

CLOSE cursor_name{光标名称}

这个语句关闭先前打开的光标。

如果光标未被明确地关闭,则它在被声明的复合语句的末尾关闭。

【例8.13】关闭名称为“cursor_fruit”的光标,SQL语句如下:

CLOSE  cursor_fruit;

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【项目总结】易到家家政服务平台 —— 派单调度(7)

派单调度需求分析 在抢单业务中,用户下单成功由服务人员或机构进行抢单,抢单成功服务人员上门服务,除了抢单业务系统还设计了派单业务,由系统根据用户订单的特点自动派给合适的服务人员。 流程如下: 首先获取待分配…

visual studio 在kylin v10上跨平台编译时c++标准库提示缺少无法打开的问题解决

情况1:提示无法打开 源文件 "string"之类导致无法编译 情况2:能编译,但无法打开这些库文件或标准库使用提示下划红色问题 解决方案: 一、通过工具->选项->跨平台里,在“远程标头IntelliSense管理器”更新下载一下…

SpringCould+vue3项目的后台用户管理的CURD【Taurus教育平台】

文章目录 一.SpringCouldvue3项目的后台用户管理的CURD【Taurus教育平台】 1.1 背景 二.用户列表(分页查询) 2.1 前端Vue3 (Vue3-Element-Admin)2.2 后端SpringCould 处理 三. 用户信息删除 3.1 前端Vue3 (Vue3-Eleme…

Eclipse 插件开发相关概念

整理了Eclipse插件开发的概念,用于熟悉入门 SWT(Standard Widget Toolkit)标准图形工具箱 Java开发的GUI程序技术,由Eclipse开发,相比AWT、Swing更美观;对于目标平台上已经有的控件,SWT会直接使…

算法之 数论

文章目录 质数判断质数3115.质数的最大距离 质数筛选204.计数质数2761.和等于目标值的质数对 2521.数组乘积中的不同质因数数目 质数 质数的定义:除了本身和1,不能被其他小于它的数整除,最小的质数是 2 求解质数的几种方法 法1,根…

AndroidStudio查看Sqlite和SharedPreference

1.查看Sqlite 使用App Inspection,这是个好东西 打开方式:View → Tool Windows → App Inspection 界面如图: App inspection不但可以看Sqlite还可以抓包network和background task连抓包工具都省了。 非常好使 2.查看sharedPreference 使…

谈一谈数据库中的死锁问题

文章目录 死锁是什么?死锁的四个必要条件避免死锁的策略 本篇文章是基于《MySQL45讲》来写的个人理解与感悟。 死锁是什么? 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。若无外力作用&a…

网络工程师 (31)VLAN

前言 VLAN(Virtual Local Area Network)即虚拟局域网,是一种将物理局域网划分成多个逻辑上独立的虚拟网络的技术。 一、定义与特点 定义:VLAN是对连接到的第二层交换机端口的网络用户的逻辑分段,不受网络用户的物理位置…

从深入理解 netty——》AI

想了很久,准备写一个系列从深入理解 netty——》AI。 先说下为啥要从netty开始,看看netty的重要性 rocketmq异步消息组件nacos微服务注册中心spring cloud gateway网关redission分布式缓存es全文检索sentinel流量控制,服务保护seata分布式…

从 0 开始本地部署 DeepSeek:详细步骤 + 避坑指南 + 构建可视化(安装在D盘)

个人主页:chian-ocean 前言: 随着人工智能技术的迅速发展,大语言模型在各个行业中得到了广泛应用。DeepSeek 作为一个新兴的 AI 公司,凭借其高效的 AI 模型和开源的优势,吸引了越来越多的开发者和企业关注。为了更好地…

在anaconda环境中构建flask项目的exe文件

一、创建并激活虚拟环境 conda create -n flask_env python3.9 # python版本根据项目需求安装 conda activate flask_env # 激活环境二、安装必要依赖 推荐使用conda,pip没尝试过,但是deepseek给出了命令 conda install flask …

腾讯云服务器中Ubuntu18.04搭建python3.7.0与TensorFlow1.15.0与R-4.0.3环境

所有踩过的坑,都化成了这条平坦的路 云服务器配置 基础配置选择竞价实例(便宜/需求小) 选择地区(距离自己近的就行) 实例配置选择异构计算(能力较强,性价比高)根据GPU显存需求选择…

金融风控项目-1

文章目录 一. 案例背景介绍二. 代码实现1. 加载数据2. 数据处理3. 查询 三. 业务解读 一. 案例背景介绍 通过对业务数据分析了解信贷业务状况 数据集说明 从开源数据改造而来,基本反映真实业务数据销售,客服可以忽略账单周期,放款日期账单金…

JAVA安全—Shiro反序列化DNS利用链CC利用链AES动态调试

前言 讲了FastJson反序列化的原理和利用链,今天讲一下Shiro的反序列化利用,这个也是目前比较热门的。 原生态反序列化 我们先来复习一下原生态的反序列化,之前也是讲过的,打开我们写过的serialization_demo。代码也很简单&…

基于Spring Boot的医院挂号就诊系统【免费送】

基于Spring Boot的医院挂号就诊系统 效果如下: 系统登陆页面 系统主页面 挂号页面 客服页面 挂号管理页面 公告信息管理页面 审核页面 在线咨询管理页面 研究背景 随着医疗技术的不断发展和人们健康意识的提高,医院作为提供医疗服务的核心机构&#x…

玩转适配器模式

文章目录 解决方案现实的举例适用场景实现方式适配器模式优缺点优点:缺点:适配器模式可比上一篇的工厂模式好理解多了,工厂模式要具有抽象的思维。这个适配器模式,正如字面意思,就是要去适配某一件物品。 假如你正在开发一款股票市场监测程序, 它会从不同来源下载 XML 格…

栈的简单介绍

一.栈 栈是一种先进后出的结构:(先出来的是45,要出12就必须先把前面的数据全部出完。) 2.实例化一个栈对象: 3.入栈: 4.出栈:(当走完pop就直接弹出45了。) 5.出栈的…

【Java】-【面试】-【Java进阶】

一、分布式 1、分布式锁 2、分布式ID 3、分布式事务

Leetcode - 周赛435

目录 一、3442. 奇偶频次间的最大差值 I二、3443. K 次修改后的最大曼哈顿距离三、3444. 使数组包含目标值倍数的最少增量四、3445. 奇偶频次间的最大差值 II 一、3442. 奇偶频次间的最大差值 I 题目链接 本题使用数组统计字符串 s s s 中每个字符的出现次数,然后…

kafka了解-笔记

文章目录 kafka快速上手Kafka介绍Kafka快速上手理解Kafka的集群工作机制Kafka集群的消息流转模型 Kafka客户端小型流转流程客户端工作机制 kafka快速上手 Kafka介绍 MQ的作用 MQ:MessageQueue,消息队列,是一种FIFO先进先出的数据结构&#…