引言

  MySQL本身提供了内置函数,这些函数的存在给我们日常的开发和数据操作带来了很大的便利,比如我前面提到过的聚合函数SUM()、AVG()以及日期时间函数等等,可是我们总会出现其他的需求:我们需要调用一个函数,这个函数需要按照我们的要求来实现我们自己的功能,可是这个函数式系统不能提供的因为这中需求的不确定性。因此我们需要自己来解决这种需求。还好MySQL设计的扩展性给了我们这个机会,我们可以通过自定义函数的功能解决这个问题。

1.MySQL自定义函数简介

  在MySQL中使用自定义函数也需要相应的要求,语法如下,

  创建新函数:

    Create function function_name(参数列表)

    returns返回值类型

    函数体内容

  相关说明,

  • 函数名:应该合法的标识符,并且不应该与已有的关键字冲突。一个函数应该属于某数据库,可以使用db_name.funciton_name的形式执行当前函数所属数据库

    ,否则默认为当前数据库。

  • 参数列表:可以有一个或者多个函数参数,甚至是没有参数也是可以的。对于每个参数,由参数名和参数类型组成。
  • 返回值:指明返回值类类型
  • 函数体:自定义函数的函数体由多条可用的MySQL语句,流程控制,变量声明等语句构成。需要指明的是函数体中一定要含有return 返回语句。

2.自定义示例

  a.无参函数定义

    

mysql> DROP FUNCTION IF EXISTS hello;
Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> DELIMITER $$
mysql> CREATE FUNCTION hello()
-> RETURNS VARCHAR(255)
-> BEGIN
-> RETURN 'Hello world,i am mysql';
-> END $$
Query OK, 0 rows affected (0.11 sec)

  调用自定义函数:

  

mysql> DELIMITER ;
mysql> SELECT hello();
+-------------------------+
| hello() |
+-------------------------+
| Hello world,i am mysql |
+-------------------------+
1 row in set (0.00 sec)

可见已经调用成功了,需要注意的几点

  之所以使用DELIMITER是因为MySQL中默认是使用分号来结束一个命令的,我们定义的函数体中一条命令写完时会用分号来结束,而MySQL会误以为函数体已经定义完成,因为我们需要定义一个新的标识符来标识一个命令的结束,因为就可以使用DELIMITER。

  b:含有参数的自定义函数

  在我们格式化日期的时候我们会调用DATE_FORMAT(date,format)函数,第一个参数是日期第二个参数是需要格式化的格式,也就是说需要传递两个参数,我们现在就把这个函数给改下

  

mysql> DELIMITER $$
mysql> DROP FUNCTION IF EXISTS test.formatDate $$
Query OK, 0 rows affected, 1 warning (0.07 sec) mysql> CREATE FUNCTION test.formatDate(fdate datetime)
-> RETURNS VARCHAR(255)
-> BEGIN
-> DECLARE x VARCHAR(255) DEFAULT '';
-> SET x= date_format(fdate,'%Y年%m月%d日%h时%i分%s秒');
-> RETURN x;
-> END $$
Query OK, 0 rows affected (0.11 sec) mysql> DELIMITER ;
mysql> SELECT formatDate(now());
+----------------------------+
| formatDate(now()) |
+----------------------------+
| 2014年11月21日03时41分21秒 |
+----------------------------+
1 row in set (0.18 sec)

  这样当我们需要定制这样的函数时就可以自己实现了,那就是通过含参的自定义函数。

3.自定义函数相关语法及变量

  a:变量声明

    DECLARE var_name[,...] type [DEFAULT value] ,这个语句被用来声明局部变量。要给变量提供一个默认值,请包含一个DEFAULT子句。值可以被指定为一个表达式,不需要为一个常数。如果没有DEFAULT子句,初始值为NULL。使用语序使用 set 和 select into语句为变量赋值。

  b:IF  条件语句、

  

IF search_conditionTHEN

statement_list

[ELSEIF search_conditionTHENstatement_list]

...

[ELSE statement_list]

ENDIF;

  c:CASE语句

  

CASE case_value

WHEN when_valueTHENstatement_list

[WHEN when_value THENstatement_list]

...

[ELSE statement_list]

END CASE; 

  d:循环语句

  

While

[begin_label:]WHILEsearch_conditionDO

statement_list

END WHILE [end_label];

退出整个循环leave 相当于break

退出当前循环iterate 相当于 continue

通过退出的标签决定退出哪个循环。

4.其他相关

  删除函数我们可以使用 DROP FUNCTION IF EXISTS function_name;

  

mysql>  SELECT hello();
+-------------------------+
| hello() |
+-------------------------+
| Hello world,i am mysql |
+-------------------------+
1 row in set (0.12 sec) mysql> DROP FUNCTION hello();
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right s
mysql> DROP FUNCTION hello;
Query OK, 0 rows affected (0.47 sec) mysql> SELECT hello();
ERROR 1305 (42000): FUNCTION test.hello does not exist

通过打印的错误可以发现有些是需要注意的

  查看定义的函数  SHOW FUCNTION STATUS LIKE 'function_name',或者是使用SHOW  CREATE FUNCTION function_name;

  

mysql> SHOW FUNCTION STATUS LIKE 'hello';
+------+-------+----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db | Name | Type | Definer | Modified | Created | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+------+-------+----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| test | hello | FUNCTION | root@localhost | 2014-11-21 14:48:05 | 2014-11-21 14:48:05 | DEFINER | | latin1 | latin1_swedish_ci | latin1_swedish_ci |
+------+-------+----------+----------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
1 row in set (0.18 sec) mysql> SHOW CREATE FUNCTION hello;
+----------+----------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------
-----------+----------------------+----------------------+--------------------+
| Function | sql_mode | Create Function
| character_set_client | collation_connection | Database Collation |
+----------+----------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------
-----------+----------------------+----------------------+--------------------+
| hello | STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`localhost` FUNCTION `hello`() RETURNS varchar(255) CHARSET latin1
BEGIN
RETURN 'Hello world,i am mysql';
END | latin1 | latin1_swedish_ci | latin1_swedish_ci |
+----------+----------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------
-----------+----------------------+----------------------+--------------------+
1 row in set (0.01 sec)

  修改函数ALTER FUNCTION  function_name  函数选项。

ALTER FUNCTION func_name [characteristic ...]

characteristic:
COMMENT 'string'
| LANGUAGE SQL
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }

  上面这个语法结构是MySQL官方给出的,修改的内容可以包含SQL语句也可以不包含,既可以是读数据的SQL也可以是修改数据的SQL还有权限。此外在修改function的时候还需要注意你不能使用这个语句来修改函数的参数以及函数体,如果你想改变这些的话你就需要删除掉这个函数然后重新创建。

  

mysql> SELECT hello();
+-------------------------+
| hello() |
+-------------------------+
| Hello world,i am mysql |
+-------------------------+
1 row in set (0.00 sec) mysql> ALTER FUNCTION hello
->
-> READS SQL DATA
-> COMMENT 'print hello';
Query OK, 0 rows affected (0.23 sec) mysql> SELECT SPECIFIC_NAME,SQL_DATA_ACCESS,
-> ROUTINE_COMMENT FROM information_schema.Routines
-> WHERE ROUTINE_NAME='hello';
+---------------+-----------------+-----------------+
| SPECIFIC_NAME | SQL_DATA_ACCESS | ROUTINE_COMMENT |
+---------------+-----------------+-----------------+
| hello | READS SQL DATA | print hello |
+---------------+-----------------+-----------------+
1 row in set (0.21 sec)

  

  

MySQL之自定义函数的更多相关文章

  1. Mysql - 存储过程/自定义函数

    在数据库操作中, 尤其是碰到一些复杂一些的系统, 不可避免的, 会用到函数/自定义函数, 或者存储过程. 实际项目中, 自定义函数和存储过程是越少越好, 因为这个东西多了, 也是一个非常难以维护的地方 ...

  2. mysql创建自定义函数与存储过程

    mysql创建自定义函数与存储过程 一 创建自定义函数 在使用mysql的过程中,mysql自带的函数可能不能完成我们的业务需求,这时就需要自定义函数,例如笔者在开发过程中遇到下面这个问题 mysql ...

  3. navicat与phpmyadmin做mysql的自定义函数和事件

    自定义函数和事件是mysql一个很方便的功能,navicat在5.1以上版本就支持了自定义函数和事件,phpmyadmim不清楚. 用这个是由于一些简单的事情,没有必要去做一个服务器计划使用 接下来我 ...

  4. MySQL(六) —— 自定义函数

    自定义函数 用户自定义函数(user-defined function, UDF)是一种对MySQL扩展的途径,其用法与内置函数相同. 参数,返回值 创建自定义函数 CREATE FUNCTION f ...

  5. MySQL 创建自定义函数

    语法:Create function function_name(参数列表)returns返回值类型 函数体 函数名,应合法的标识符,不应与系统关键字冲突. 一个函数应该属于某个数据库,可以使用db_ ...

  6. mysql增加自定义函数功能

    mysql默认是不能自定义函数的 当create function时 This function has none of DETERMINISTIC, NO SQL, or READS SQL DAT ...

  7. MySQL 创建自定义函数(1)

    1. 创建测试自定义函数(1) CREATE DEFINER=`dbdh`@`localhost` FUNCTION `test`.`sp_function_dbdh_three`() RETURNS ...

  8. MySQL之自定义函数实例讲解

    转自:https://www.2cto.com/database/201804/740205.html MySQL中已经有很多函数,如时间函数等,但是有时这些函数不能满足自己的设计需求,此时需要自定义 ...

  9. Jpa 重写方言dialect 使用oracle / mysql 数据库自定义函数

    在使用criteria api进行查询时 criteriaBuilder只提供了一个部分标准的sql函数,但当我们需要使用oracle特有的行转列函数wm_concat或 mysql特有的行转列函数g ...

随机推荐

  1. 8年,属于 HTML 5 春天的到来悄悄!

    [核心提示] 在 8 年时间中,HTML 5 为整个行业都带来了什么.标准终于确定后又会产生什么样的变革呢? 微博微信Twitter对于非常多人来说,非常有可能在微信的朋友圈里玩过「围住神经猫」,也非 ...

  2. WebKit介绍及总结(一)

    一 . WebKit 简单介绍 Webkit 是一个开放源码的浏览器引擎 (web browser engine) ,最初的代码来自 KDE 的 KHTML 和 KJS( 均开放源码 ) .苹果公司在 ...

  3. JavaEE(12) - JPA规范及实现(TopLink和Hibernate)

    1. JPA规范与ORM框架之间的联系 JPA规范并不属于EJB3规范,它是一套完全独立的规范,不仅可以在基于EJB的JavaEE应用程序中使用,而且完全可以在普通JavaSE应用程序中使用. JPA ...

  4. linux下一个Oracle11g RAC建立(四)

    linux下一个Oracle11g RAC建立(四) 三.配置共享存储 配置ASM管理准备 1)OCRDISK :存储CRS资源配置信息 2)VOTEDISK:仲裁盘.记录节点状态 3)DataDis ...

  5. Display Database Image using MS SQL Server 2008 Reporting Services

    原文 Display Database Image using MS SQL Server 2008 Reporting Services With the new release of MS SQL ...

  6. .NET中使用Redis(二)

    很久以前写了一篇文章 .NET中使用Redis 介绍了如何安装Redis服务端,以及如何在.NET中调用Redis读取数据.本文简单介绍如何设计NoSQL数据库,以及如何使用Redis来存储对象. 和 ...

  7. Android - 错: java.lang.IllegalStateException: Already attached

    错: java.lang.IllegalStateException: Already attached 本文地址: http://blog.csdn.net/caroline_wendy 可能原因: ...

  8. DirectX11 学习笔记3 - 创建一个立方体 和 轴

    该方案将在进一步的程序 面向对象. 独立的模型类.更像是一个框架. 其中以超过遇到了一个非常有趣的问题,.获得一晚.我读了好几遍,以找到其他的列子.必须放在某些功能Render里面实时更新,而不是仅仅 ...

  9. TS流文件

    简单介绍编辑 随着从HDTV录制的高清节目在网上的流传,烧友们对TS这个名词大概已经不陌生了.但随之而来就是怎样播放.怎样加入字幕等等的一系列问题.本文将重点介绍一下这方面的应用操作. 先来简要介绍一 ...

  10. Meteor入门

    转载Meteor入门介绍   Meteor是什么 基于nodejs的实时web APP开发框架. Meteor能带来什么 简单的说,你可以用js搞定客户端.服务端的开发.另外,客户端.服务端的界限被极 ...