MySQL 函数:字符串、数字、用户定义、存储

是什么 MySQL 功能?
MySQL 不仅可以存储和检索数据。 它也可以 对数据进行操作 在检索或保存之前。那就是 MySQL 函数就派上用场了。函数其实就是一段代码,它执行一个操作并返回结果。有些函数接受参数,而有些函数则不接受参数。
我们来看一个例子。默认情况下, MySQL 以“YYYY-MM-DD”格式保存日期数据类型。假设我们开发了一个应用程序,用户希望以“DD-MM-YYYY”格式返回日期。我们可以使用 MySQL 可以使用内置函数 DATE_FORMAT 来实现这一点。DATE_FORMAT 是 Python 中最常用的函数之一。 MySQL我们将在本课后面详细探讨这个问题。
无论其类型如何,一个函数 始终返回单个值, 可以接受零个或多个参数 括号内的内容,以及 可以在任何允许使用表达式的地方使用。 — 在 SELECT 列表、WHERE 子句或 ORDER BY 子句中。
为何使用 MySQL 功能?
既然我们已经了解了什么是函数,那么下一个问题是,我们为什么要将这项工作推送到数据库中。
如上图所示,一个函数接受一个输入值,在数据库引擎内部应用一次逻辑,并将一个结果返回给每个请求该结果的应用程序。
程序员可能会想:“何必呢?” MySQL 函数?同样的效果也可以用脚本语言或编程语言实现。”的确,我们可以通过在应用程序中编写过程来实现这一点。
回到我们的 DATE 示例,为了让用户获得所需格式的数据,业务层必须自行进行必要的处理。
当应用程序必须与其他系统集成时,这就会成为一个问题。当我们使用 MySQL 诸如DATE_FORMAT之类的函数,其功能已嵌入数据库中,任何需要数据的应用程序都能以所需的格式获取数据。 减少业务逻辑中的重复工作,并减少数据不一致。.
另一个需要考虑的原因 MySQL 它们的功能在于可以帮助减少客户端/服务器应用程序中的网络流量。业务层只需调用已存储的函数,无需通过网络拉取原始数据行进行操作。平均而言,使用函数可以显著提升系统整体性能。
有哪些 MySQL 功能
既然“是什么”和“为什么”的问题都已明确,我们现在可以来看一下这三类功能。 MySQL 提供:内置函数、存储函数和用户自定义函数。
内建功能
MySQL 它捆绑了许多内置函数——这些函数已经在……中实现。 MySQL 服务器。它们允许我们对数据执行多种类型的操作,并可分为以下几个常用类别。
- 字符串函数 – 对字符串数据类型进行操作
- 数值函数 – 对数字数据类型进行操作
- 日期功能 – 对日期数据类型进行操作
- 汇总功能 – 对所有上述数据类型进行操作并生成汇总结果集。
- 其他功能 – MySQL 它还支持其他类型的内置函数,但本课程仅限于上述组。
现在让我们详细了解一下上面提到的每个分组。我们将使用“Myflixdb”示例数据库来解释最常用的功能。
字符串函数
字符串函数操作的是文本值。在我们的电影表中,标题以大小写混合的方式存储。假设我们想要查询返回全部大写的标题。“UCASE”函数接受一个字符串作为参数,并将每个字母转换为大写,如下面的脚本所示。
SELECT `movie_id`, `title`, UCASE(`title`) AS `upper_case_title` FROM `movies`;
点击这里
- UCASE(`title`) 这是一个内置函数,它接受标题作为参数,并以大写字母返回标题。
- AS `upper_case_title` 为计算列添加别名,以便结果集包含可读的标题而不是原始表达式。
在以下位置执行上述脚本 MySQL 使用 Workbench 对 Myflixdb 进行测试,得到的结果如下所示。
| 电影 ID | 标题 | upper_case_title |
|---|---|---|
| 16 | 67% 有罪 | 67%的人有罪 |
| 6 | 天使与魔鬼 | 天使与魔鬼 |
| 4 | Code 黑 | 代号“黑衣” |
| 5 | 爸爸的小女孩 | 爸爸的小女儿们 |
| 7 | 达芬奇 Code | 达芬奇密码 |
| 2 | 忘掉莎拉·马歇尔 | 忘掉莎拉·马歇尔 |
| 9 | Honey moonERS | 蜜糖 MOONERS |
| 19 | 电影3 | 电影 3 |
| 1 | 加勒比海盗4 | 加勒比海盗4 |
| 18 | 样片 | 样片 |
| 17 | 大独裁者 | 大独裁者 |
| 3 | X-战警 | X-MEN |
除了 UCASE 之外,还有两位伙伴值得我们铭记: LCASE 将字符串转换为小写,并且 康卡特 将两个或多个字符串合并成一个字符串。完整列表请参见…… MySQL 字符串函数引用.
数值函数
如前所述,数值函数作用于数值数据类型。我们也可以直接在 SQL 语句中对数值数据执行数学计算。
算术运算符
MySQL 支持以下算术运算符,可用于在 SQL 语句中执行计算。
| 姓名 | 描述 |
|---|---|
| DIV | 整数除法 |
| / | 分部 |
| – | 小组tracTION |
| + | 增加 |
| * | 乘法 |
| % 或 MOD | 系数 |
以下是每个运算符的示例。
整数除法 (DIV) — DIV 函数会舍弃小数部分,只返回整数部分。
SELECT 23 DIV 6;
执行上述脚本后,我们会得到以下结果。 3.
除法运算符 (/) — 与 DIV 运算符不同,除法运算符会保留结果的小数部分。
SELECT 23 / 6;
执行上述脚本后,我们会得到以下结果。 3.8333.
小组trac运算符(-)
SELECT 23 - 6;
执行上述脚本后,我们会得到以下结果。 17.
加法运算符 (+)
SELECT 23 + 6;
执行上述脚本后,我们会得到以下结果。 29.
乘法运算符 (*)
SELECT 23 * 6 AS `multiplication_result`;
结果:
| 乘法结果 |
|---|
| 138 |
取模运算符(% 或 MOD)
取模运算符将 N 除以 M,得到余数。让我们来看一个取模运算符的例子,使用与前面例子相同的值。
SELECT 23 % 6; -- OR, equivalently: SELECT 23 MOD 6;
执行任一脚本都会给我们带来以下结果 5.
现在让我们看看 MySQL.
FLOOR 此函数会移除数字的小数位,并将其向下取整到最接近的整数。以下脚本演示了它的用法。
SELECT FLOOR(23 / 6) AS `floor_result`;
结果:
| 地板结果 |
|---|
| 3 |
圆型行李箱 此函数将数字四舍五入到最接近的整数。因为 23 / 6 的计算结果为 3.8333,所以 ROUND 返回 4,而 FLOOR 返回 3——两者不能互换使用。
SELECT ROUND(23 / 6) AS `round_result`;
结果:
| 轮次结果 |
|---|
| 4 |
兰德 此函数生成一个随机数。每次调用该函数时,其值都会改变。以下脚本演示了它的用法。
SELECT RAND() AS `random_result`;
日期功能
日期函数可处理日期和日期时间数据类型。DATE_FORMAT 函数解决了引言中提到的“YYYY-MM-DD 与 DD-MM-YYYY”格式的问题。
日期格式 该脚本接受两个参数:要格式化的日期值,以及由占位符构成的格式字符串。以下脚本会以用户要求的“日-月-年”格式返回每个发布日期。
SELECT `title`, DATE_FORMAT(`date_released`, '%d-%m-%Y') AS `formatted_date` FROM `movies`;
下面列出了最常用的格式占位符。
| 占位符 | 意 | 输出示例 |
|---|---|---|
| %d | 月份中的日期,两位数 | 04 |
| %m | 月份,两位数 | 08 |
| %Y | 年份,四位数 | 2012 |
| %M | 月份全称 | 八月 |
| %他的 | Hours分钟,秒 | 14:35:09 |
日常工作中还会经常用到其他三个日期函数:
- 更新() 返回当前日期,格式为 YYYY-MM-DD。
- 现在() 返回当前日期 和 时间。
- DATEDIFF(d1, d2) 返回两个日期之间的天数——这是任何逾期租金报告的基础。
完整列表请参见: MySQL 日期和时间函数参考.
存储函数
内置函数可以满足常见需求。当业务规则更加具体时,我们需要编写自定义函数——这就是存储函数的作用。
存储函数与内置函数的行为方式完全相同,区别在于它们需要由您自行定义。创建后,存储函数可以像其他任何函数一样在 SQL 语句中使用。基本语法如下所示。
CREATE FUNCTION sf_name ([parameter(s)]) RETURNS data_type [DETERMINISTIC | NOT DETERMINISTIC] BEGIN -- procedural statements END
点击这里
- “CREATE FUNCTION sf_name ([parameter(s)])” 是强制性的,并说明 MySQL 服务器创建一个名为 `sf_name` 的函数,括号内定义了可选参数。
- “返回数据类型” 是必填项,用于指定函数返回的数据类型。
- **确定性** 声明无论提供相同的参数,该函数都返回相同的值。 “非决定论的” 表达了相反的观点。
- “开始……结束” 封装函数执行的过程代码。
假设我们想知道哪些租借的电影已经过了归还日期。我们可以创建一个存储函数,该函数接受归还日期作为参数,并将其与服务器上的当前日期进行比较。如果当前日期晚于归还日期,则表示电影已逾期,我们返回“是”;否则,我们返回“否”。
DELIMITER | CREATE FUNCTION sf_past_movie_return_date (return_date DATE) RETURNS VARCHAR(3) NOT DETERMINISTIC BEGIN DECLARE sf_value VARCHAR(3); IF CURDATE() > return_date THEN SET sf_value = 'Yes'; ELSEIF CURDATE() <= return_date THEN SET sf_value = 'No'; END IF; RETURN sf_value; END| DELIMITER ;
⚠️警告——不要将此函数标记为DETERMINISTIC。 函数体调用了 CURDATE() 函数,因此同一个参数今天可能返回“否”,明天可能返回“是”。将时间相关的函数声明为 DETERMINISTIC 会误导优化器,并且对于基于语句的复制是不安全的。 不确定 每当主体调用 CURDATE()、NOW() 或 RAND() 时。
执行上述脚本会创建存储函数 `sf_past_movie_return_date`。现在让我们来测试一下。
SELECT `movie_id`, `membership_number`, `return_date`, CURDATE(), sf_past_movie_return_date(`return_date`) AS `is_overdue` FROM `movierentals`;
在以下位置执行上述脚本 MySQL 使用 Workbench 对 myflixdb 数据库进行测试,得到以下结果。
| 电影 ID | 会员号码 | 归期 | 更新() | 已逾期 |
|---|---|---|---|---|
| 1 | 1 | 无 | 04-08-2012 | 无 |
| 2 | 1 | 25-06-2012 | 04-08-2012 | 是 |
| 2 | 3 | 25-06-2012 | 04-08-2012 | 是 |
| 2 | 2 | 25-06-2012 | 04-08-2012 | 是 |
| 3 | 3 | 无 | 04-08-2012 | 无 |
注意这两行 NULL 值。当 `return_date` 为 NULL 时,两个比较的结果都为 NULL 而不是 TRUE 或 FALSE,因此两个 IF 分支都不会执行,函数返回 NULL——这是预期结果,因为未归还的电影没有归还日期可供比较。
用户定义函数
当仅使用 SQL 速度不够快时, MySQL 还有第三种选择。用户自定义函数 (UDF) 是用编译型语言编写的,例如: C or C++用户自定义函数 (UDF) 被构建到共享库中,并注册到服务器。添加后,它们的调用方式与其他函数相同。由于 UDF 作为本地代码在服务器进程中运行,因此它适合处理繁重的计算任务——但 UDF 中的一个错误可能会导致服务器崩溃,所以 UDF 的使用频率远低于存储函数。
内置函数、存储函数和用户自定义函数:你应该使用哪一个?
这三个函数族都返回同一个值,并且可以从任何 SQL 语句中调用,但它们的区别在于编写者、运行环境以及风险程度。下表总结了这些区别。
| 标准 | 内建功能 | 存储函数 | 用户自定义函数(UDF) |
|---|---|---|---|
| 谁写的 | 附带 MySQL | 你,在 SQL 中 | 你,在 C 或 C++ |
| 居住地 | 服务器内部 | 在数据库中,使用 CREATE FUNCTION 创建 | 服务器加载的已编译共享库 |
| 典型用途 | 格式化、数学运算、聚合 | 可重用的业务规则,例如逾期支票 | SQL 无法表达 CPU 密集型或专门的逻辑 |
| 主要风险 | 没有 | 如果逐行调用大表,速度会很慢。 | 库中的崩溃可能会导致服务器宕机。 |
一般来说,先尝试使用内置函数。如果没有合适的内置函数,则编写一个存储函数,以便将规则集中在一处。只有当存储函数的运行速度明显过慢时,才考虑使用用户自定义函数 (UDF)。

