前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL 函数的一个小tip

MySQL 函数的一个小tip

作者头像
AsiaYe
发布2023-03-08 19:29:16
4320
发布2023-03-08 19:29:16
举报
文章被收录于专栏:DBA随笔DBA随笔

MySQL 函数的一个小tip

今天上班的时候,同事问了一个问题,关于MySQL函数的。说实话,这方面积累确实比较少,主要原因是函数和存储过程都偏向于业务逻辑,在线上环境一般不建议使用,开发人员应该尽可能将这些业务逻辑写在业务代码里面,而不是让数据库去操作。数据库应该去做它擅长的事情,例如数据的增删改查之类的。

但是,这也不是说线上环境,就不允许使用函数和存储过程,有些存量的历史业务,可能改造起来成本过高,收益和成本不成正比,所以数据库里面还是有这些数据形态存在。

01

问题介绍

这个具体的函数问题,可以拆分为以下几个:

1、如何查看MySQL函数的详细信息?

这个问题其实还好,在MySQL5.7和MySQL8.0里面,我们都可以通过information_schema.routines和information_schema.parameters来查看函数的相关信息。

其中routines表显示的是函数的创建信息;parameters表显示的是函数的参数信息。

来看下面例子:

创建一个简单的函数:

代码语言:javascript
复制
mysql> create function myf1 (param1 int) returns int 
mysql> no sql  
mysql> begin 
mysql> return (select 2); 
mysql> end//
Query OK, 0 rows affected (0.02 sec)

简单解释下这个SQL吧:

param1 int代表我们的输入参数是一个整数;

returns int代表函数返回值是个整数;

no sql表示函数体不包含SQL语句;

return (select 2)是真正的函数体。

函数的创建信息:

代码语言:javascript
复制
mysql> select * from information_schema.routines where routine_schema='test' \G
*************************** 1. row ***************************
           SPECIFIC_NAME: myf1
         ROUTINE_CATALOG: def
          ROUTINE_SCHEMA: test
            ROUTINE_NAME: myf1
            ROUTINE_TYPE: FUNCTION
               DATA_TYPE: int
CHARACTER_MAXIMUM_LENGTH: NULL
  CHARACTER_OCTET_LENGTH: NULL
       NUMERIC_PRECISION: 10
           NUMERIC_SCALE: 0
      DATETIME_PRECISION: NULL
      CHARACTER_SET_NAME: NULL
          COLLATION_NAME: NULL
          DTD_IDENTIFIER: int
            ROUTINE_BODY: SQL
      ROUTINE_DEFINITION: begin return (select 2); end
           EXTERNAL_NAME: NULL
       EXTERNAL_LANGUAGE: SQL
         PARAMETER_STYLE: SQL
        IS_DETERMINISTIC: NO
         SQL_DATA_ACCESS: NO SQL
                SQL_PATH: NULL
           SECURITY_TYPE: DEFINER
                 CREATED: 2023-01-09 06:26:05
            LAST_ALTERED: 2023-01-09 06:26:05
                SQL_MODE: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
         ROUTINE_COMMENT:
                 DEFINER: root@%
    CHARACTER_SET_CLIENT: utf8mb4
    COLLATION_CONNECTION: utf8mb4_0900_ai_ci
      DATABASE_COLLATION: utf8mb4_0900_ai_ci

函数的参数信息:

代码语言:javascript
复制
mysql> select * from information_schema.parameters where specific_schema='test'\G
*************************** 1. row ***************************
        SPECIFIC_CATALOG: def
         SPECIFIC_SCHEMA: test
           SPECIFIC_NAME: myf1
        ORDINAL_POSITION: 0
          PARAMETER_MODE: NULL
          PARAMETER_NAME: NULL
               DATA_TYPE: int
CHARACTER_MAXIMUM_LENGTH: NULL
  CHARACTER_OCTET_LENGTH: NULL
       NUMERIC_PRECISION: 10
           NUMERIC_SCALE: 0
      DATETIME_PRECISION: NULL
      CHARACTER_SET_NAME: NULL
          COLLATION_NAME: NULL
          DTD_IDENTIFIER: int
            ROUTINE_TYPE: FUNCTION
*************************** 2. row ***************************
        SPECIFIC_CATALOG: def
         SPECIFIC_SCHEMA: test
           SPECIFIC_NAME: myf1
        ORDINAL_POSITION: 1
          PARAMETER_MODE: IN
          PARAMETER_NAME: param1
               DATA_TYPE: int
CHARACTER_MAXIMUM_LENGTH: NULL
  CHARACTER_OCTET_LENGTH: NULL
       NUMERIC_PRECISION: 10
           NUMERIC_SCALE: 0
      DATETIME_PRECISION: NULL
      CHARACTER_SET_NAME: NULL
          COLLATION_NAME: NULL
          DTD_IDENTIFIER: int
            ROUTINE_TYPE: FUNCTION

注意红色的部分,就是问题所在。

第二行好理解,就是我们传入的参数param1,它的mode是IN,类型为int。

第一行包含参数名为Null的参数,它的mode也是Null,类型是int

2、为什么输入参数只有1个,单数parameter里面还有一行PARAMETER_MODE=Null,PARAMETER_NAME=Null 的记录?

这个问题当时确实比较模糊,主要是对于Null值不太清楚,查了查官方文档,找到了结果。

  • PARAMETER_MODE The mode of the parameter. This value is one of IN, OUT, or INOUT. For a stored function return value, this value is NULL.
  • PARAMETER_NAME The name of the parameter. For a stored function return value, this value is NULL.
  • DATA_TYPE The parameter data type. The DATA_TYPE value is the type name only with no other information. The DTD_IDENTIFIER value contains the type name and possibly other information such as the precision or length.

简单翻译一下:

对于PARAMETER_MODE字段,正常取值是in,out或者inout,但是对于函数返回值,这个值是NULL;我们没有定义param1参数的取值,原因在官方文档中也有体现:

Specifying a parameter as IN, OUT, or INOUT is valid only for a PROCEDURE. For a FUNCTION, parameters are always regarded as IN parameters.(对于函数,参数总是被视作in类型)

对于PARAMETER_NAME字段,正常取值是参数名字,对于函数返回值,这个值是NULL;

对于DATA_TYPE字段,这个字段只返回类型名字,而不包含其他信息,例如类型长度。也就意味着如果函数返回值是varchar(10),这个字段也会只显示varchar,而没有长度信息。长度信息需要在另外一个字段DTD_IDENTIFIER上去获取。

到这里,这个小问题就解决了。相信不长使用函数的小伙伴,肯定也有收获。

最近很少搞MySQL相关的东西,抽空水一篇,今天就到这里吧。晚安。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-01-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档