參考:http://blog.csdn.net/qq_35246620/article/details/70823903
函數
函數,就是將一段代碼封裝到一個結構中,在需要執行該段代碼的時候,直接調用該結構(函數)執行即可。此操作,實現了代碼的複用。在 MySQL 中,函數有兩種,分別爲:系統函數和自定義函數。
系統函數
顧名思義,系統函數就是系統定義好的函數,在需要的時候,我們直接調用即可。
任何函數都有返回值(對於空函數,我們就認爲其返回值爲空
),而且在 MySQL 中任何有返回值的操作都是通過select
來操作的,因此 MySQL 的函數調用就是通過select
來實現的。
在 MySQL 中,字符是字符串操作中最常見的基本單位。此外,如果對中文的截取是按字節進行的話,很容易造成亂碼的問題。
下面,我們介紹一些常見的、對字符進行操作的系統函數:首先,執行如下語句,定義一些變量,
set @cn = '你好世界';
set @en = 'hello world';
set @one = 'charies';
set @two = 'gavin';
set @three = 'Gavin';
select @cn, @en, @one, @two, @three;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
然後,調用系統函數進行測試:
substring
,截取字符串,單位爲字符;
如上圖所示,在 MySQL 中字符串的位置是從1
開始,0
含有特殊的意義。
char_length
,獲取字符長度;length
,獲取字節長度;
instr
,判斷字符串中某個子串是否存在,存在則返回具體的位置,不存在則返回0
;
lpad
,左填充,將字符串按照某個指定的填充方式,填充到指定(字符)長度;
如上圖所示,在對@en
進行填充的時候,填充結果爲hellohellhello world
,其中第二個hello
並沒有填充全,這是因爲系統函數lpad
的第二個參數限定的了變量@en
的具體長度,如示例中我們設置其爲20
,而原@en
的長度爲11
,因此只能向@en
中在填充9
個字符。
insert
,找到目標位置,將指定長度的字符串替換爲目標字符串;
如上圖所示,insert
函數並沒有修改變量自身的值,只是對變量的值進行加工而已。
strcmp
,比較字符串的大小;
如上圖所示,在用strcmp
函數對字符串進行比較的時候不區分大小寫(默認校對集),並用0
表示兩個字符串相等;用-1
表示第一個參數的字符串小於第二個參數的字符串;用1
表示第一個參數的字符串大於第二個參數的字符串。
自定義函數
對於任意一個函數,其都包含如下要素:
- 函數名;
- 參數類別(可以爲空);
- 返回值;
- 函數體(作用域)。
根據上面這些函數要素,我們就來嘗試創建自定義函數。
創建函數
-- 基本語法
create function 函數名([參數列表]) returns 數據類型
begin
-- 函數體
-- 返回值,類型爲 returns 指定的數據類型
end
- 1
- 2
- 3
- 4
- 5
- 6
如果我們定義的函數的函數體內僅含有返回值,則可以省略begin
和end
。此外,自定義函數和系統函數的調用方式相同。執行如下語句,進行測試:
-- 自定義函數
create function showLove() returns int
return 521;
-- 調用自定義函數
select showLove();
- 1
- 2
- 3
- 4
- 5
查看函數
查看函數,基本語法爲:
show function status + [like 'pattern'];
如上圖所示,我們可以看到showLove
函數是屬於test
數據庫的,這引出了函數的一個性質,即函數是屬於具體數據庫的,在一個數據庫定義的函數不能在其定義的數據庫外使用,但是可以查看。
查看函數的創建語句,基本語法爲:
show create function + 函數名;
修改函數 & 刪除函數
函數只能先刪除後新增,不能修改。刪除函數的基本語法爲:
drop function + 函數名;
執行如下語句,進行測試:
-- 刪除函數
drop function showLove;
-- 查看函數
show function status like 'showLove'\G;
- 1
- 2
- 3
- 4
函數參數
對於函數的參數,一共有兩種,分別爲形參和實參,其中,形參可以理解爲定義函數時使用的參數,且形參必須指定數據類型;實參可以理解爲在調用函數時傳入的值或變量。因此,函數定義的具體形式應該爲:
function 函數名(形參名字 形參類型) returns 返回數據類型
下面,我們定義一個函數,完成一個簡單的需求,即求1
到指定數值的和。代碼如下:
delimiter $$
create function addAll(num int) returns int
begin
-- 定義條件變量
set @i = 1;
set @res = 0; -- 保存求和結果
-- 循環求和
while @i <= num do
-- 任何變量想要修改值都必須使用 set 關鍵字,且 MySQL 中沒有 += 或者 ++ 運算符
set @res = @res + @i;
-- 修改循環變量
set @i = @i + 1;
end while;
-- 返回求和結果
return @res;
end
$$
delimiter ;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
如上圖所示,函數已經定義成功。接下來,執行如下語句,進行測試:
-- 調用函數求和
select addAll(100);
-- 查詢自定義變量 @res 和 @i
select @res, @i;
- 1
- 2
- 3
- 4
- 5
如上圖所示,求和函數addAll
已經正確執行。此外,我們發現在函數內部使用@
符號定義的變量@res
和@i
在函數外部也是可以查看使用的,這說明:使用@
符號定義的變量爲全局變量。
變量作用域
在 MySQL 中,變量的作用域有兩種,分別爲全局和局部,其中,全局變量可以在任何地方使用;局部變量只能在函數內部使用。
- 全局變量:使用
set
關鍵字定義,用@
符號標識; - 局部變量:使用
declare
關鍵字聲明,且所用的局部變量必須在函數體開始之前進行聲明。
接下來,我們利用局部變量定義一個函數,完成一個簡單的需求,即求1
到指定數值的和,要求10
的倍數不加。代碼如下:
delimiter $$
create function addAll2(num int) returns int
begin
-- 聲明變量,包含循環變量和結果變量
declare i int default 1; -- 定義局部變量可以含有屬性
declare res int default 0;
-- 循環求和
mywhile:while i <= num do
-- 條件判斷
if i % 10 = 0 then
-- 修改循環變量
set i = i + 1;
-- 重新循環
iterate mywhile;
end if;
-- 修改結果變量
set res = res + i;
-- 修改循環變量
set i = i + 1;
end while;
-- 返回求和結果
return res;
end
$$
delimiter ;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
如上圖所示,函數已經定義成功。接下來,執行如下語句,進行測試:
-- 調用函數求和
select addAll(100), addAll2(100);
- 1
- 2
如上圖所示,函數已經正確執行。