自定義函數:
用戶自定義函數(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)!