MariaDB/MySQL存储过程和函数
从现在开始,努力学习吧!本文《MariaDB/MySQL存储过程和函数》主要讲解了存储、函数、MySQL等等相关知识点,我会在golang学习网中持续更新相关的系列文章,欢迎大家关注并积极留言建议。下面就先一起来看一下本篇正文内容吧,希望能帮到你!
在MySQL/MariaDB中,存储过程(stored procedure)、存储函数(stored function)、触发器(trigger)、事件(event)统称为存储程序(stored programs)。此外,存储过程和存储函数还合称为stored routines。
对于函数来说,除了存储函数,还有用户自定义函数(UDF,user defined function),在MySQL/MariaDB中,用户自定义函数是存储函数的扩展,它像一个小程序一样,需要编译、安装后才能运行。这和SQL Server对UDF的定义不同,倒是类似于SQL Server的CLR程序。
虽然存储过程和存储函数在功能实现上有些区别,但在使用方法上几乎一致。
1.创建存储过程、函数
在MySQL/MariaDB中创建存储过程、函数的语法如下:其中OR REPLACE是MariaDB 10.1.3版本中才有的,MySQL中不支持OR REPLACE。
-- 创建存储过程和函数
CREATE [OR REPLACE] PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
CREATE [OR REPLACE] FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
proc_parameter:
[ IN | OUT | INOUT ] param_name type
func_parameter:
param_name type
type:
Any valid MySQL data type
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
routine_body:
Valid SQL routine statement
在MySQL/MariaDB的存储过程和函数中,允许存在DML和DDL语句。且存储过程中还允许(存储函数不允许)使用SQL事务类型的语句,例如提交commit。当然,肯定也支持嵌套其他存储过程或函数。
存储过程的参数有三种类型:IN、OUT和INOUT,下文将详细分析这三种类型参数。
在创建和修改的语法中,需要说明的就是characteristic部分,这部分基本没什么用,但可以了解下它们是干什么的。
- language sql:表示后面的body部分使用标准SQL语句编写,这是默认的。该选项的作用是为了以后支持非SQL语句书写存储过程和函数的,例如SQL Server中就有使用.NET写的CLR存储过程、函数、触发器等。但目前,这个还没有任何意义。
- [not] deterministic:deterministic的意思是确定的。这里的意思是函数返回值是明确的,而非具有随机性的值。例如,使用了随机数,使用了now()这样的函数等。not deterministic表示返回值是不确定的,这是系统默认值。当优化器知道函数返回值是确定值时,将选择一个更优化的执行计划。如果返回值是确定的,却定义为not deterministic,则性能会降低,如果返回值是不确定的,却定义为deterministic,则报错。
- {contains sql|no sql|reads sql data|modifies sql data}:这些是提供给服务器的信息类子句,看上去是约束性语句,但MariaDB不会根据它们做任何检查。也就是说,这些提示符只是给人看的,没有任何作用。contains sql表示body不包含读和写数据的语句,例如SET和DO;no sql表示body不包含SQL语句;reads sql data表示body包含读数据的语句,但不包含写数据的语句,如SELECT。modifies sql data表示body包含写数据的语句,如DELETE/UPDATE;如果没有指定这些特征值,则使用默认值contains sql。
- sql security:指明执行该程序时以谁的身份执行。definer表示执行时获取创建者的权限,invoker表示以调用者的身份执行,若调用该程序的用户对程序中涉及的对象没有对应的权限则会执行失败(如lisa用户有执行存储过程的权限,但是没有读取存储过程中涉及的表a的权限,那么执行存储过程时因为读表失败而导致执行被拒绝)。默认是definer。
- comment:程序的注释信息。
当要调用存储过程或函数时,可以使用call命令调用存储过程,如call sp_name();;而函数则可以当作表达式一样进行调用,例如使用select命令select func();,当作表达式赋值给变量set @a=func()。
需要注意的是,在MySQL/MariaDB中,因为语句的结束符是分号";",在存储过程或函数创建过程中直接使用分号会导致语句报错。所以当存储过程或存储函数中包含需要使用分号的语句时,应在创建存储过程或函数之前使用delimiter命令来暂时改变语句结束符,在创建完毕之后再改回结束符为分号";"。
例如:
delimiter $$
create or replace procedure proc() -- procedure name
begin -- procedure body
select * from A;
end $$
delimiter ;
--调用存储过程
call proc();
在上面的语句中,首先定义了结束符为$$;然后判断了存储过程proc()是否存在,存在则删除,之后才开始创建存储过程。这个存储过程很简单,只是一个select语句。创建语句结束之后,再次使用delimiter命令将结束符改回了分号";"。最后使用call命令进行了存储过程的调用。
以下是一个函数的创建和使用示例:
delimiter $$
create or replace function func1()
returns int
return (select count(*) from t1);$$
delimiter ;
set @c=func1();
select func1(),@c;
+---------+------+
| func1() | @c |
+---------+------+
| 6 | 6 |
+---------+------+
1.1 存储过程的IN、OUT和INOUT
它们表示的是参数的类型。
IN参数类型表示将调用者给定的值传递给存储过程。存储过程可能会修改这个值,但是对于调用者来说,在存储过程返回结果时,所做的修改是不可见的。
OUT参数类型表示将存储过程的返回值传递给调用者。其初始值为NULL,当存储过程返回时,这个值对调用者来说是可见的。
INOUT参数类型表示由调用者传递值给存储过程,存储过程可能会修改这个值,当存储过程返回的时候,所做的修改对调用者来说是可见的。
对于每个OUT或INOUT类型的参数,当调用者在CALL语句中调用存储过程时,所传递的每个用户变量都可以在存储过程返回的时候获取其值。
默认每个参数都是IN。要指定其他类型的参数,可以在参数名前面使用关键字OUT或INOUT。
(1).IN参数类型。
IN参数类型是指调用者将某个值传递给存储过程,存储过程借用这个值来完成某些操作。
以下是IN类型参数的示例。
create or replace table t1(a int);
insert into t1 values(1),(2),(3),(4),(5),(6);
delimiter $$
create or replace procedure proc1(min int,max int)
begin
select * from t1 where t1.a >= min and t1.a max;
end$$
delimiter ;
call proc1(3,5);
+------+
| a |
+------+
| 3 |
| 4 |
| 5 |
+------+
(2).OUT参数类型。
OUT参数类型是指存储过程将某个值通过该参数返回给调用者。因此调用者必须传递一个用户变量给存储过程,用来记录存储过程OUT参数的值。这个用户变量在传递给存储过程之前,可以是一个已赋值的变量,但在传递给存储过程时,将自动初始化为NULL值。
以下是OUT类型参数的示例。在此示例中,传入@a给proc(),最后将count(*)赋值给out参数cnt,cnt代表的就是传入参数@a。
delimiter $$
create or replace procedure proc2(out cnt int)
begin
select count(*) into cnt from A;
end$$
delimiter ;
call proc1(@a);
select @a as a;
a
--------
6
(3).INOUT参数类型。
INOUT参数类型指的是调用者和存储过程之间传递的内容可以互相赋值。INOUT有两个过程,一个是IN的过程,这个过程是将调用者指定的值传递给存储过程,另一个是OUT的过程,这个过程是存储过程将某个返回值返回给调用者。因此,调用者传递INOUT参数时,也必须传递一个用户变量。但与OUT不同的是,INOUT的用户变量有初始值,这个初始值会直接应用在存储过程中。而OUT的用户变量虽然也有初始值,但这个初始值会自动转换为NULL。
以下是INOUT参数类型的示例。
/* procedure INOUT */
create or replace table t1(a int);
insert into t1 values(1),(2),(3),(4),(5),(6);
delimiter $$
create or replace procedure proc3(INOUT cnt int,min int,max int)
begin
if cnt 5 then /* 直接用cnt这个INOUT参数来判断大小,因为它继承了传递时的值 */
select count(*) into cnt from t1 where t1.a >=min and t1.a max;
else
select count(*) into cnt from t1;
end if;
end$$
delimiter ;
set @a=3;
set @b=6;
call proc1(@a,3,5);
call proc1(@b,3,5);
select @a,@b;
+------+------+
| @a | @b |
+------+------+
| 3 | 6 |
+------+------+
2.修改和删除存储过程、函数
可以使用alter语句修改存储过程、函数,但alter语句只能修改characteristic部分,不支持对body部分和参数部分修改。若要修改它们,只能先删除再创建。
-- 修改存储过程和函数
ALTER {PROCEDURE | FUNCTION} proc_name [characteristic ...]
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
删除存储过程和函数的方式很简单,直接使用drop命令,但要求有alter权限。
drop {procedure|function} [if exists] sp_name
3.查看存储过程、函数信息
查看存储过程和函数的信息。
show {procedure|function} status like 'pattern'; -- 查看routine的基本信息
show create {procedure|function} proc_name; -- 查看routine的创建语句
show {procedure|function} code routine_name; -- 查看MariaDB内部是如何操作routine中各语句的
从
information_schema.routines中查看存储过程和函数的信息,这个比show status更详细一点。
select * from information_schema.routines where routine_name='xxx'\G
这里说明下show code功能,这个功能必须要在支持debug的MariaDB上才能使用,可以在编译时使用选项"--with-debug"启用该功能。
例如:
DELIMITER $$
CREATE PROCEDURE p1 ()
BEGIN
DECLARE fanta INT DEFAULT 55;
DROP TABLE t2;
LOOP
INSERT INTO t3 VALUES (fanta);
END LOOP;
END$$
delimiter ;
SHOW PROCEDURE CODE p1;
+-----+----------------------------------------+
| Pos | Instruction |
+-----+----------------------------------------+
| 0 | set fanta@0 55 |
| 1 | stmt 9 "DROP TABLE t2" |
| 2 | stmt 5 "INSERT INTO t3 VALUES (fanta)" |
| 3 | jump 2 |
+-----+----------------------------------------+
其中第一列是从0开始的序列值,表示存储过程中所执行的动作先后顺序。第二列是mariadb要执行的动作,这些动作是基于存储过程中的源语句进行设置的。
今天关于《MariaDB/MySQL存储过程和函数》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!
超详细的MySQL数据库升级
- 上一篇
- 超详细的MySQL数据库升级
- 下一篇
- 一文带你了解MySQL是如何优化in子查询的,其实非常简单
-
- 数据库 · MySQL | 1天前 |
- MySQL数值函数大全及使用技巧
- 117浏览 收藏
-
- 数据库 · MySQL | 2天前 |
- 三种登录MySQL方法详解
- 411浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- MySQL数据备份方法与工具推荐
- 420浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- MySQL数据备份方法与工具推荐
- 264浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL索引的作用是什么?
- 266浏览 收藏
-
- 数据库 · MySQL | 5天前 |
- MySQL排序原理与实战应用
- 392浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQLwhere条件查询技巧
- 333浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL常用数据类型有哪些?怎么选更合适?
- 234浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL常用命令大全管理员必学30条
- 448浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL高效批量插入数据方法大全
- 416浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL性能优化技巧大全
- 225浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL数据备份4种方法保障安全
- 145浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3167次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3380次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3409次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4513次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3789次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- golang中的defer函数理解
- 2022-12-22 366浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览

