MySQL不仅内置了一些常用函数,同时也支持自定义函数,来满足开发者的需求

函数定义

MySQL的函数定义语法如下:

    CREATE  [DEFINER = { user | CURRENT_USER }]FUNCTION functionName ( varName varType [, ... ] )RETURNS returnVarType[characteristic ...] routine_body
  • functionName:函数名,同MySQL内置函数一样,大小写不敏感
  • varName: 形参名
  • varType: 形参类型,其与varName配对使用。形参数量不限( ≥0\geq 0≥0)
  • returnVarType: 返回值类型。函数必须有且只能有一个返回值
  • characteristic:函数特性,下将详述
  • routine_body:函数体。函数体中必须含有 return 语句,当函数体为复合结构时,需要使用begin … end 语句

characteristic的可用参数值如下:

| 值 | 说明 | | :-: | :-: | | language sql | 指明函数体的语言类型, 目前仅支持sql | | [not] deterministic | deterministic 指明函数的结果是确定的,即相同的输入会得到相同的输出;not deterministic意为结果不确定。默认为 not deterministic | | { contains sql | no sql | reads sql data | modifies sql data } | 指明函数体使用sql语句的限制。contains sql意为函数体包含sql语句,但不包含读写数据的sql语句;no sql意为函数体不包含sql语句;reads sql data意为函数体包含读数据sql语句;modifies sql data意为函数体包含写数据的sql语句。默认为contains sql | | sql security { definer | invoker } | 指明谁有权限执行该函数。definer意为只有定义者才能执行;invoker意为拥有权限的调用者可以执行。默认为definer | | comment ‘message’ | 函数的注释信息,指明函数的功能 |

示例如下:

  • 函数体为简单结构:
    create    function myfun_getAvg(num1 int, num2 int)    comment '计算两个数的均值'returns int    return (num1+num2)/2;
  • 函数体为复合结构:
    createfunction myfun_getMax(num1 int, num2 int)returns int        begindeclare res int;if(num1 > num2) thenset res = num1;elseif (num1 < num2) thenset res = num2;elseset res = num1;end if;return res;end;

变量

局部变量

定义在sql语句块中的变量,常见于存储过程和函数的 begin … end 中,语句块执行完后局部变量则结束生命周期

声明定义

函数中可以通过 declare 声明定义局部变量,其作用域为 begin … end 的函数体中。默认初值为nul,可以通过default指定该语句中所有定义变量的初值

declare var [, ...] varType [defualt initVal];

Note: declare声明定义语句,必须放在begin…end函数体中最前面的位置

赋值

  • 通过set给变量赋值
    set var = expression [, var = expression, ...];set var := expression [, var = expression, ...];

[Note]: sql下的 = 操作符是比较(判定是否相等)操作符,只有在set语句中可作为赋值操作符使用。故在其他语句中,赋值操作应该使用 := 操作符

  • 通过select into 给变量赋值

通过select语句将所查询出的字段数据依次赋值到 into 后的变量中。值得一提的是,当select查询结果为空时(即,无记录),则不对变量进行赋值操作;当select查询的结果不止一条时,MySQL将报错,函数执行失败

select filed1 [, ...] into var1 [, ...] from tableName where conditon

示例

    createfunction myfunTest(idx int)returns intcomment '测试函数'begindeclare res int;                    # 声明定义1个变量, 初值默认为 nulldeclare num1, num2 int  default 27;     # 声明定义多个变量,初值全部为27declare data1, data2 int;       # 声明定义多个变量,初值全部默认为 nullset num2 = 23, res = num1 + num2;       # 使用set语句, = 操作符赋值set data1 = 1, data2 = 1;select num, price into  data1, data2 from test2 where id = idx;     # 使用 select into 语句set res :=  res * (data1 + data2);      # 使用set语句, := 操作符赋值return (res);end;

函数测试结果如下:

用户变量

定义在当前客户端的连接下的变量,其作用域在当前客户端连接下均有效,当当前客户端断开连接后则该变量结束生命周期。其对其他客户端连接不可见

赋值

用户变量无需先行声明创建,直接赋值使用即可。赋值时,当前客户端下若无该用户变量,则会自动创建并完成赋值;查看一个不存在的用户变量时(e.g., select @foo)返回null。需要注意的是,用户变量的变量名必须以 @ 开头

  • 通过set 赋值
    set @varName = val;     # 对名为 @varName 用户变量赋值set @varName := val;    # 对名为 @varName 用户变量赋值select @varName;         # 查看名为 @varName 用户变量的值
  • 通过 select 赋值

通过select语句将所查询出的字段数据赋值到变量中,需要注意的是,只能使用 := 操作符赋值

    select @varName:=field [as field] [, ...] from tableName where condition;select @varName:=Val;

示例

常用流程控制

if 语句

    if condition thenstatements[ elseif condition thenstatements ][ elsestatements ]end if;

示例如下:

    createfunction getLevelByScore(score int)returns varchar(255)comment '根据成绩获取评级'begindeclare leavel varchar(255);if (score >= 90) thenset leavel = '优秀';elseif (score >= 80) thenset leavel = '中等';elseif (score >= 60) thenset leavel = '及格';elseset leavel = '不及格';end if;return leavel;end;

测试结果如下:

while 语句

    [label:] while condition dostatmentsend while [label]

示例如下:

    createfunction getSum(num int)returns intcomment '计算0-num的和'begindeclare i,sum int default 0;while (i<=num) doset sum = sum + i;set i = i + 1;end while;return sum;end;

测试结果如下:

leave、iterate

levae 和 iterate 分别用于循环控制的跳出整个循环 和 跳过循环体的剩余部分并直接进行下一次循环,作用相当于C语言中的 break和 continue。区别在于C语言中的break、continue都是针对所在层循环的控制。而levae 和 iterate是针对label所标注的循环的控制,故其可以实现从最内层循环直接跳出

    levae label;    # 跳出label所标注的循环结构iterate label;  # 跳过循环体的剩余部分,直接开始label所标注的下一次循环

示例1:

    createfunction testLeave()returns varchar(255)begindeclare i,j int default 0;loop1: while (i<=5) doset j = 0;while (j<=i) doif(j = 3) thenleave loop1;end if;set j = j + 1;end while;set i = i + 1;end while loop1;return concat('i: ', i, ' j:', j);end;

测试结果如下:

示例2:

    createfunction testIterate()returns varchar(255)begindeclare i,j int default 0;loop1: while (i<=5) doset i = i + 1;set j = 0;while (j<=i) doif(j = 3) theniterate loop1;end if;set j = j + 1;end while;end while loop1;return concat('i: ', i, ' j:', j);end;

测试结果如下:

函数相关的操作

查看函数状态

通过show status 命令查看函数的相关信息。可以在其后面使用 like 语句进行函数名匹配,其中functionName同样支持 % 进行模糊匹配

show function status [like functionName];

示例如下:

查看函数定义

通过show create 命令查看函数的定义内容

show create function functionName;

示例如下:

修改函数特性

通过alter function实现对函数特性characteristic的修改,注意,不是对函数定义内容的修改

alter function functionName [characteristic ...]

示例如下:

删除函数

通过drop function 删除函数。当指定函数不存在时,会报错,可以添加 if exists 避免出现报错

drop function [if exists] functionName

测试结果如下:

Note

在命令行中其默认将 ; 符号作为结束符来执行语句。所以如果我们在命令行中创建函数,需要使用 delimiter 命令重定义结束符 如下图所示,先通过 delimiter ∗∗将结束符更改为∗∗** 将结束符更改为 **∗∗将结束符更改为∗∗ (可随意更改,一般常用$$)再创建函数。函数创建完毕后,通过我们重定义后的结束符结束(即 $$ )。最后不要忘记,通过 delimiter ; 将结束符重新修改为 ;

测试结果如下:

[if exists] functionName


测试结果如下:[外链图片转存中...(img-TiWtHIFD-1637660782830)]## Note在命令行中其默认将 **;** 符号作为结束符来执行语句。所以如果我们在命令行中创建函数,需要使用 delimiter 命令重定义结束符 如下图所示,先通过 **delimiter $$** 将结束符更改为 **$$** (可随意更改,一般常用\$\$)再创建函数。函数创建完毕后,通过我们重定义后的结束符结束(即 **$$** )。最后不要忘记,通过 **delimiter ;** 将结束符重新修改为 **;**[外链图片转存中...(img-Q6G9fZyO-1637660782832)]测试结果如下:![img](https://img-blog.csdnimg.cn/img_convert/ffd9d866a601194ab9dd7d9e1bdf10f1.png)

Mysql 复习笔记- 基础篇12 [函数定义概述]相关推荐

  1. MySQL学习笔记-基础篇1

    MySQL 学习笔记–基础篇1 目录 MySQL 学习笔记--基础篇1 1. 数据库概述与MySQL安装 1.1 数据库概述 1.1.1 为什么要使用数据库 1.2 数据库与数据库管理系统 1.2.1 ...

  2. MySQL学习笔记-基础篇2

    MySQL学习笔记-基础篇2 目录 MySQL学习笔记-基础篇2 8.子查询 8.1 需求分析与问题解决 8.1.1 实际问题 8.1.2 子查询的基本使用 8.1.3 子查询的分类 8.2 单行子查 ...

  3. MySQL数据库笔记-基础篇

    文章目录 MySQL概述 数据库相关概念 小总结 MySQL数据库 版本: 启动与停止 客户端连接 关系型数据库 数据模型 小总结 SQL SQL通用语法 SQL分类 DDL 数据库操作 查询 创建 ...

  4. 【QT开发笔记-基础篇】| 第二章 常用控件 | 2.12 表格控件 QTableWidget

    本节对应的视频讲解:B_站_链_接 QTableWidget 是 Qt 中的表格控件,可以行列的形式来展示数据 1. 属性和方法 QTableWidget 有很多属性和方法,完整的可查看帮助文档. 在 ...

  5. 数据库MySQL学习笔记高级篇(周阳)

    数据库MySQL学习笔记高级篇 1. mysql的架构介绍 mysql简介 高级Mysql mysqlLinux版的安装 mysql配置文件 mysql逻辑架构介绍 mysql存储引擎 2. 索引优化 ...

  6. Google Map 开发笔记——基础篇(Javascript )

    Google Map 开发笔记--基础篇 说明: 一.使用入门: 1.在您需要显示地图的 html 页面嵌入这段 script 2.地图 DOM 元素 3.初始化地图 二.地图画点.线.面 1.标记( ...

  7. Redis学习笔记①基础篇_Redis快速入门

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...

  8. Python复习笔记——基础知识

    Python复习笔记-基础知识 文章目录 Python复习笔记-基础知识 Python变量 基于值的内存管理方式 赋值语句的执行过程 Python定义变量名的规范 运算符和表达式 加+ 乘* 除/ % ...

  9. Vue学习笔记进阶篇——Render函数

    本文为转载,原文:Vue学习笔记进阶篇--Render函数 基础 Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编 ...

最新文章

  1. 8天学通MongoDB——第三天 细说高级操作
  2. Java NIO 选择器(Selector)的内部实现(poll epoll)
  3. BER_TLV格式简介
  4. DB2 SQL查询结果集自动编号、返回条数范围控制研究
  5. 2013\National _C_C++_B\4.高僧斗法
  6. 带你快速了解 Docker 和 Kubernetes
  7. ElementUI改变el-table的表头颜色以及各行的颜色
  8. Ajax — 第五天
  9. P3293 [SCOI2016]美味
  10. html中心对齐,html – 对齐内联块中心
  11. as运行时不报错却闪退_字典访问不存在的key 时,如何才能不报错?
  12. 网络爬虫之java基础篇QueryRunner(Ⅲ)
  13. lock 线程 java_Java多线程之Lock的应用
  14. 《绝地求生》外挂源代码被公布,或迎神仙大战时代?
  15. 洛谷 P1312 Mayan游戏
  16. Flink Forward Asia 2020,明天见!
  17. Create directory命令
  18. 解决win10下桌面右击新建没有文本文档(.txt)的问题
  19. RS485无线通讯模块工作原理及应用场景
  20. linux操作系统基础及应用课后答案,Linux操作系统课后习题答案及复习要点

热门文章

  1. 海夕漫科技:店铺有等级之分吗
  2. idea注释信息配置
  3. 总结新GRE作文的写作和分析思路
  4. Python3 去掉json中带的注释
  5. 【编程语言】CentOS 7 下pip更新命令
  6. PullScrollView详解(五)——完全使用listview实现下拉回弹(方法二)
  7. 银河麒麟系统+飞腾CPU 部署nginx(运行vue项目)
  8. 基于python的智能语音助手下载_GitHub - qq53182347/DuerOS-Python-Client: 基于DuerOS的个人的智能语音助手...
  9. webpack5 - 之 生产环境的优化(dist压缩包、copy静态资源、缓存、代码切片、多线程打包、抽离重复代码 与 最小化 entry chunk)
  10. SpringBoot报错:Error starting ApplicationContext. To display the conditions report re-run your applica