MySQL自定義函數

自定義函數:

用戶自定義函數(user-defined function,UDF)是一種對MySQL擴展的途經,其用法與內置函數相同。

自定義函數有兩個必要條件:
1. 參數
2. 返回值

函數可以返回任意類型的值,同樣可以接收這些類型的參數。

函數的參數和返回值之間沒有必然的內在的聯系。

示例1:
創建一個無參數的函數,返回當前時間的,年月日 時分秒。
例如:

mysql>?SELECT?NOW();  +---------------------+  |?NOW()???????????????|  +---------------------+  |?2016-09-08?21:17:17?|  +---------------------+  1?row?in?set?(0.00?sec)    mysql>?SELECT?DATE_FORMAT(NOW(),'%Y年%m月%d日?%H點:%i分:%s秒');  +--------------------------------------------------+  |?DATE_FORMAT(NOW(),'%Y年%m月%d日?%H點:%i分:%s秒')?????????????|  +--------------------------------------------------+  |?2016年09月08日?21點:19分:54秒????????????????????????????????|  +--------------------------------------------------+  1?row?in?set?(0.01?sec)

對上述過程經行封裝:

mysql>?CREATE?FUNCTION?f1()?RETURNS?VARCHAR(30)  ????->?RETURN?DATE_FORMAT(NOW(),'%Y年%m月%d日?%H點:%i分:%s秒');Query?OK,?0?rows?affected?(0.08?sec)    mysql>?SELECT?f1();  +-------------------------------+  |?f1()??????????????????????????|  +-------------------------------+  |?2016年09月08日?21點:21分:25秒?????????????|  +-------------------------------+  1?row?in?set?(0.02?sec)

注:returns后面的為返回值類型,return后面的為返回值。

示例2:
創建有參數的函數,例如求兩個數的平均值。

mysql>?CREATE?FUNCTION?f2(num1?SMALLINT?UNSIGNED,?num2?SMALLINT?UNSIGNED)  ????->?RETURNS?FLOAT(10,2)?UNSIGNED  ????->?RETURN?(num1+num2)/2;Query?OK,?0?rows?affected?(0.00?sec)

調用:

mysql>?SELECT?f2(4,6);  +---------+  |?f2(4,6)?|  +---------+  |????5.00?|  +---------+  1?row?in?set?(0.02?sec)

如果要刪除上面所創建的兩個自定義函數:

mysql>?DROP?FUNCTION?f2;Query?OK,?0?rows?affected?(0.11?sec)    mysql>?DROP?FUNCTION?f1;Query?OK,?0?rows?affected?(0.00?sec)

創建具有復合結構函數體的自定義函數

例如:創建一個函數向表中插入數據,并返回所插入數據的id。

mysql>?DESC?tdb_test;  +------------+------------------+------+-----+---------+----------------+  |?Field??????|?Type?????????????|?Null?|?Key?|?Default?|?Extra??????????|  +------------+------------------+------+-----+---------+----------------+  |?id?????????|?int(10)?unsigned?|?NO???|?PRI?|?NULL????|?auto_increment?|  |?first_name?|?varchar(20)??????|?NO???|?????|?NULL????|????????????????|  |?last_name??|?varchar(20)??????|?NO???|?????|?NULL????|????????????????|  +------------+------------------+------+-----+---------+----------------+  3?rows?in?set?(0.00?sec)    mysql>?CREATE?FUNCTION?adduser(first_name?VARCHAR(20),last_name?VARCHAR(20))  ????->?RETURNS?INT?UNSIGNED  ????->?RETURN  ????->?INSERT?tdb_test(first_name,last_name)?VALUES(first_name,last_name);  ????ERROR?1064?(42000):?You?have?an?error?in?your?SQL?syntax;?  ????check?the?manual?that?corresponds?to?your?MySQL?server?version?for?the?right?syntax?to?use?near?'tdb_test(first_name,last_name)?  ????VALUES(first_name,last_name)'?at?line?4

這時我們發現,在輸入要執行的sql語句后,后面的分號為當前默認的分隔符,導致函數無法再繼續輸入。因此需要修改默認的分隔符。

mysql>?DELIMITER?//

意思是用//結束

  mysql>?CREATE?FUNCTION?adduser(first_name?VARCHAR(20),last_name?VARCHAR(20))  ????->?RETURNS?INT?UNSIGNED  ????->?RETURN  ????->?INSERT?tdb_test(first_name,last_name)?VALUES(first_name,last_name);  ????->?LAST_INSERT_ID();  ????->?//  ERROR?1064?(42000):?You?have?an?error?in?your?SQL?syntax;?check?the?manual?that?corresponds?to?your?MySQL?server?version?for?the?right?syntax?to?  use?near?'tdb_test(first_name,last_name)?VALUES(first_name,last_name);  LAST_INSERT_ID()'?at?line?4

同樣返回錯誤,因為,返回有兩個語句要執行,需放入begin和end構成一個聚合體,下面來看正確的做法。

mysql>?CREATE?FUNCTION?adduser(first_name?VARCHAR(20),last_name?VARCHAR(20))  ????->?RETURNS?INT?UNSIGNED  ????->?BEGIN  ????->?INSERT?tdb_test(first_name,last_name)?VALUES(first_name,last_name);  ????->?RETURN?LAST_INSERT_ID();  ????->?END  ????->?//  Query?OK,?0?rows?affected?(0.00?sec)

再將分隔符改回來

mysql>?DELIMITER?;

測試結果如下:

mysql>?SELECT?adduser("ttt","ddd");  +----------------------+  |?adduser("ttt","ddd")?|  +----------------------+  |????????????????????5?|  +----------------------+  1?row?in?set?(0.11?sec)    mysql>?SELECT?*?FROM?tdb_test;  +----+------------+-----------+  |?id?|?first_name?|?last_name?|  +----+------------+-----------+  |??1?|?A??????????|?B?????????|  |??2?|?Jack???????|?Bob???????|  |??3?|?tom%???????|?123???????|  |??4?|?11?????????|?22????????|  |??5?|?ttt????????|?ddd???????|  +----+------------+-----------+  5?rows?in?set?(0.00?sec)

關于函數體

  • 函數體由合法的sql語句構成;

  • 函數體可以是簡單的SELECT或INSERT語句;

  • 函數體如果為復合結構則使用BEGIN…END語句;

  • 復合結構可以包含聲明,循環,控制結構;

刪除函數:

DROP?FUNCTION?[IF?EXISTS]?function_name

自定義函數:

用戶自定義函數(user-defined function,UDF)是一種對MySQL擴展的途經,其用法與內置函數相同。

自定義函數有兩個必要條件:
1. 參數
2. 返回值

函數可以返回任意類型的值,同樣可以接收這些類型的參數。

函數的參數和返回值之間沒有必然的內在的聯系。

示例1:
創建一個無參數的函數,返回當前時間的,年月日 時分秒。
例如:

mysql>?SELECT?NOW();  +---------------------+  |?NOW()???????????????|  +---------------------+  |?2016-09-08?21:17:17?|  +---------------------+  1?row?in?set?(0.00?sec)    mysql>?SELECT?DATE_FORMAT(NOW(),'%Y年%m月%d日?%H點:%i分:%s秒');  +--------------------------------------------------+  |?DATE_FORMAT(NOW(),'%Y年%m月%d日?%H點:%i分:%s秒')?????????????|  +--------------------------------------------------+  |?2016年09月08日?21點:19分:54秒????????????????????????????????|  +--------------------------------------------------+  1?row?in?set?(0.01?sec)

對上述過程經行封裝:

mysql>?CREATE?FUNCTION?f1()?RETURNS?VARCHAR(30)  ????->?RETURN?DATE_FORMAT(NOW(),'%Y年%m月%d日?%H點:%i分:%s秒');Query?OK,?0?rows?affected?(0.08?sec)    mysql>?SELECT?f1();+-------------------------------+|?f1()??????????????????????????|  +-------------------------------+|?2016年09月08日?21點:21分:25秒?????????????|  +-------------------------------+1?row?in?set?(0.02?sec)

注:returns后面的為返回值類型,return后面的為返回值。

示例2:
創建有參數的函數,例如求兩個數的平均值。

mysql>?CREATE?FUNCTION?f2(num1?SMALLINT?UNSIGNED,?num2?SMALLINT?UNSIGNED)  ????->?RETURNS?FLOAT(10,2)?UNSIGNED  ????->?RETURN?(num1+num2)/2;Query?OK,?0?rows?affected?(0.00?sec)

調用:

mysql>?SELECT?f2(4,6);+---------+|?f2(4,6)?|  +---------+|????5.00?|  +---------+1?row?in?set?(0.02?sec)

如果要刪除上面所創建的兩個自定義函數:

mysql>?DROP?FUNCTION?f2;Query?OK,?0?rows?affected?(0.11?sec)    mysql>?DROP?FUNCTION?f1;Query?OK,?0?rows?affected?(0.00?sec)

創建具有復合結構函數體的自定義函數

例如:創建一個函數向表中插入數據,并返回所插入數據的id。

mysql>?DESC?tdb_test;  +------------+------------------+------+-----+---------+----------------+  |?Field??????|?Type?????????????|?Null?|?Key?|?Default?|?Extra??????????|  +------------+------------------+------+-----+---------+----------------+  |?id?????????|?int(10)?unsigned?|?NO???|?PRI?|?NULL????|?auto_increment?|  |?first_name?|?varchar(20)??????|?NO???|?????|?NULL????|????????????????|  |?last_name??|?varchar(20)??????|?NO???|?????|?NULL????|????????????????|  +------------+------------------+------+-----+---------+----------------+  3?rows?in?set?(0.00?sec)    mysql>?CREATE?FUNCTION?adduser(first_name?VARCHAR(20),last_name?VARCHAR(20))  ????->?RETURNS?INT?UNSIGNED  ????->?RETURN  ????->?INSERT?tdb_test(first_name,last_name)?VALUES(first_name,last_name);  ????ERROR?1064?(42000):?You?have?an?error?in?your?SQL?syntax;?check?the?manual?that?corresponds?to?your?MySQL?server?version?for?the?right?syntax?to?  ????use?near?'tdb_test(first_name,last_name)?VALUES(first_name,last_name)'?at?line?4

這時我們發現,在輸入要執行的sql語句后,后面的分號為當前默認的分隔符,導致函數無法再繼續輸入。因此需要修改默認的分隔符。

mysql>?DELIMITER?//

意思是用//結束

mysql>?CREATE?FUNCTION?adduser(first_name?VARCHAR(20),last_name?VARCHAR(20))  ????->?RETURNS?INT?UNSIGNED  ????->?RETURN  ????->?INSERT?tdb_test(first_name,last_name)?VALUES(first_name,last_name);  ????->?LAST_INSERT_ID();  ????->?//  ERROR?1064?(42000):?You?have?an?error?in?your?SQL?syntax;?check?the?manual?that?corresponds?to?your?  MySQL?server?version?for?the?right?syntax?to?use?near?'tdb_test(first_name,last_name)?VALUES(first_name,last_name);  LAST_INSERT_ID()'?at?line?4

同樣返回錯誤,因為,返回有兩個語句要執行,需放入begin和end構成一個聚合體,下面來看正確的做法。

mysql>?CREATE?FUNCTION?adduser(first_name?VARCHAR(20),last_name?VARCHAR(20))  ????->?RETURNS?INT?UNSIGNED  ????->?BEGIN  ????->?INSERT?tdb_test(first_name,last_name)?VALUES(first_name,last_name);  ????->?RETURN?LAST_INSERT_ID();  ????->?END  ????->?//  Query?OK,?0?rows?affected?(0.00?sec)

再將分隔符改回來

mysql>?DELIMITER?;

測試結果如下:

mysql>?SELECT?adduser("ttt","ddd");  +----------------------+  |?adduser("ttt","ddd")?|  +----------------------+  |????????????????????5?|  +----------------------+  1?row?in?set?(0.11?sec)    mysql>?SELECT?*?FROM?tdb_test;  +----+------------+-----------+  |?id?|?first_name?|?last_name?|  +----+------------+-----------+  |??1?|?A??????????|?B?????????|  |??2?|?Jack???????|?Bob???????|  |??3?|?tom%???????|?123???????|  |??4?|?11?????????|?22????????|  |??5?|?ttt????????|?ddd???????|  +----+------------+-----------+  5?rows?in?set?(0.00?sec)

關于函數體

  • 函數體由合法的sql語句構成;

  • 函數體可以是簡單的SELECT或INSERT語句;

  • 函數體如果為復合結構則使用BEGIN…END語句;

  • 復合結構可以包含聲明,循環,控制結構;

刪除函數:

DROP?FUNCTION?[IF?EXISTS]?function_name

?以上就是MySQL自定義函數的內容,更多相關內容請關注PHP中文網(www.php.cn)!

? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享