mysql之自定義函數


引言

  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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM