MySQL存儲過程/存儲過程與自定義函數的區別
---------------------------存儲過程--------------------
語法:
創建存儲過程:
CREATE [definer = {user|current_user}] PROCEDURE sp_name ([ proc_parameter [,proc_parameter ...]]) [ characteristics..] routime_body
其中:
proc_parameter : [IN|OUT|INOUT] parameter_name type
其中IN表示輸入參數,OUT表示輸出參數,INOUT表示既可以輸入也可以輸出;param_name表示參數名稱;type表示參數的類型
存儲過程體中可以使用自定義函數(UDF)中使用的復合結構/流程控制/SQL語句/自定義變量等等內容,
調用存儲過程:
CALL sp_name ([ proc_parameter [,proc_parameter ...]])
CALL sp_name
說明:當無參時,可以省略"()",當有參數時,不可省略"()"
存儲過程修改:
ALTER語句修改存儲過程只能修改存儲過程的註釋等無關緊要的東西,不能修改存儲過程體,所以要修改存儲過程,方法就是刪除重建!
刪除存儲過程:
DROP PROCEDURE [IF EXISTS] sp_name
示例:
創建無參存儲過程:
delimiter // CREATE PROCEDURE showTime() BEGIN SELECT now(); END// delimiter ; CALL showTime;
作用:顯示當前時間,沒什麽實際意義
創建含參存儲過程:
只有一個IN參數
delimiter // CREATE PROCEDURE seleById(IN uid SMALLINT UNSIGNED) BEGIN SELECT * FROM son WHERE id = uid; END// delimiter ; call seleById(2);
包含IN參數和OUT參數
delimiter // CREATE PROCEDURE deleteById(IN uid SMALLINT UNSIGNED, OUT num SMALLINT UNSIGNED) BEGIN DELETE FROM son WHERE id = uid; SELETE row_count() into num; END// delimiter ; call seleById(2,@changeLine); SELETE @changeLine;
說明:創建存儲過程deleteById,包含一個IN參數和一個OUT參數.調用時,傳入刪除的ID和保存被修改的行數值的用戶變量@changeLine,select @changeLine;輸出被影響行數.
區別:
存儲過程與自定義函數的區別: 存儲過程實現的過程要復雜一些,而函數的針對性較強; 存儲過程可以有多個返回值,而自定義函數只有一個返回值; 存儲過程一般獨立的來執行,而函數往往是作為其他SQL語句的一部分來使用;
存儲過程存在的必要性(好處):
存儲過程說白了就是把經常使用的SQL語句或業務邏輯封裝起來,預編譯保存在數據庫中,當需要的時候從數據庫中直接調用,省去了編譯的過程.
提高了運行速度;
同時降低網絡數據傳輸量(你覺得傳一堆SQL代碼快,還是傳一個存儲過程名字和幾個參數快???)
---------------------------函數用法--------------------
自定義函數 (user-defined function UDF)就是用一個象ABS() 或 CONCAT()這樣的固有(內建)函數一樣作用的新函數去擴展MySQL。
所以UDF是對MySQL功能的一個擴展
創建和刪除自定義函數語法:
創建UDF:
CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name type,...])
RETURNS {STRING|INTEGER|REAL}
runtime_body
簡單來說就是:
CREATE FUNCTION 函數名稱(參數列表)
RETURNS 返回值類型
函數體
刪除UDF:
DROP FUNCTION function_name
調用自定義函數語法:
SELECT function_name(parameter_value,...)
語法示例:
創建簡單的無參UDF
CREATE FUNCTION simpleFun()RETURNS VARVHAR(20) RETURN "Hello World!";
說明:
UDF可以實現的功能不止於此,UDF有兩個關鍵點,一個是參數,一個是返回值,UDF可以沒有參數,但UDF必須有且只有一個返回值
在函數體重我們可以使用更為復雜的語法,比如復合結構/流程控制/任何SQL語句/定義變量等等
復合結構定義語法:
在函數體中,如果包含多條語句,我們需要把多條語句放到BEGIN...END語句塊中
DELIMITER // CREATE FUNCTION IF EXIST deleteById(uid SMALLINT UNSIGNED) RETURNS VARCHAR(20) BEGIN DELETE FROM son WHERE id = uid; RETURN (SELECT COUNT(id) FROM son); END//
修改默認的結束符語法:
DELIMITER // 意思是修改默認的結束符";"為"//",以後的SQL語句都要以"//"作為結尾
特別說明:
UDF中,REURN語句也包含在BEGIN...END中
自定義函數中定義局部變量語法:
DECLARE var_name[,varname]...date_type [DEFAULT VALUE];
簡單來說就是:
DECLARE 變量1[,變量2,... ]變量類型 [DEFAULT 默認值]
這些變量的作用範圍是在BEGIN...END程序中,而且定義局部變量語句必須在BEGIN...END的第一行定義
示例:
DELIMITER // CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, Y SMALLINT UNSIGNED) RETURNS SMALLINT BEGIN DECLARE a, b SMALLINT UNSIGNED DEFAULT 10; SET a = x, b = y; RETURN a+b; END//
上邊的代碼只是把兩個數相加,當然,沒有必要這麽寫,只是說明局部變量的用法,還是要說明下:這些局部變量的作用範圍是在BEGIN...END程序中
為變量賦值語法:
SET parameter_name = value[,parameter_name = value...]
SELECT INTO parameter_name
eg:
...在某個UDF中... DECLARE x int; SELECT COUNT(id) FROM tdb_name INTO x; RETURN x; END//
用戶變量定義語法:(可以理解成全局變量)
SET @param_name = value
SET @allParam = 100; SELECT @allParam;
上述定義並顯示@allParam用戶變量,其作用域只為當前用戶的客戶端有效
自定義函數中流程控制語句語法:
存儲過程和函數中可以使用流程控制來控制語句的執行。
MySQL中可以使用IF語句、CASE語句、LOOP語句、LEAVE語句、ITERATE語句、REPEAT語句和WHILE語句來進行流程控制。
每個流程中可能包含一個單獨語句,或者是使用BEGIN...END構造的復合語句,構造可以被嵌套
1.IF語句
IF語句用來進行條件判斷。根據是否滿足條件,將執行不同的語句。其語法的基本形式如下:
IF search_condition THEN statement_list [ELSEIF search_condition THEN statement_list] ... [ELSE statement_list] END IF
其中,search_condition參數表示條件判斷語句;statement_list參數表示不同條件的執行語句。
註意:MYSQL還有一個IF()函數,他不同於這裏描述的IF語句
下面是一個IF語句的示例。代碼如下:
IF age>20 THEN SET @count1=@count1+1; ELSEIF age=20 THEN SET @count2=@count2+1; ELSE SET @count3=@count3+1; END IF;
該示例根據age與20的大小關系來執行不同的SET語句。
如果age值大於20,那麽將count1的值加1;如果age值等於20,那麽將count2的值加1;
其他情況將count3的值加1。IF語句都需要使用END IF來結束。
2.CASE語句
CASE語句也用來進行條件判斷,其可以實現比IF語句更復雜的條件判斷。CASE語句的基本形式如下:
CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement_list] ... [ELSE statement_list] END CASE
其中,case_value參數表示條件判斷的變量;
when_value參數表示變量的取值;
statement_list參數表示不同when_value值的執行語句。
CASE語句還有另一種形式。該形式的語法如下:
CASE WHEN search_condition THEN statement_list [WHEN search_condition THEN statement_list] ... [ELSE statement_list] END CASE
其中,search_condition參數表示條件判斷語句;
statement_list參數表示不同條件的執行語句。
下面是一個CASE語句的示例。代碼如下:
CASE age WHEN 20 THEN SET @count1=@count1+1; ELSE SET @count2=@count2+1; END CASE ;
代碼也可以是下面的形式:
CASE WHEN age=20 THEN SET @count1=@count1+1; ELSE SET @count2=@count2+1; END CASE ;
本示例中,如果age值為20,count1的值加1;否則count2的值加1。CASE語句都要使用END CASE結束。
註意:這裏的CASE語句和“控制流程函數”裏描述的SQL CASE表達式的CASE語句有輕微不同。這裏的CASE語句不能有ELSE NULL子句
並且用END CASE替代END來終止!!
3.LOOP語句
LOOP語句可以使某些特定的語句重復執行,實現一個簡單的循環。
但是LOOP語句本身沒有停止循環的語句,必須是遇到LEAVE語句等才能停止循環。
LOOP語句的語法的基本形式如下:
[begin_label:] LOOP statement_list END LOOP [end_label]
其中,begin_label參數和end_label參數分別表示循環開始和結束的標誌,這兩個標誌必須相同,而且都可以省略;
statement_list參數表示需要循環執行的語句。
下面是一個LOOP語句的示例。代碼如下:
add_num: LOOP SET @count=@count+1; END LOOP add_num ;
該示例循環執行count加1的操作。因為沒有跳出循環的語句,這個循環成了一個死循環。
LOOP循環都以END LOOP結束。
4.LEAVE語句
LEAVE語句主要用於跳出循環控制。其語法形式如下:
LEAVE label
其中,label參數表示循環的標誌。
下面是一個LEAVE語句的示例。代碼如下:
add_num: LOOP SET @count=@count+1; IF @count=100 THEN LEAVE add_num ; END LOOP add_num ;
該示例循環執行count加1的操作。當count的值等於100時,則LEAVE語句跳出循環。
5.ITERATE語句
ITERATE語句也是用來跳出循環的語句。但是,ITERATE語句是跳出本次循環,然後直接進入下一次循環。
ITERATE語句只可以出現在LOOP、REPEAT、WHILE語句內。
ITERATE語句的基本語法形式如下:
ITERATE label
其中,label參數表示循環的標誌。
下面是一個ITERATE語句的示例。代碼如下:
add_num: LOOP SET @count=@count+1; IF @count=100 THEN LEAVE add_num ; ELSE IF MOD(@count,3)=0 THEN ITERATE add_num; SELECT * FROM employee ; END LOOP add_num ;
該示例循環執行count加1的操作,count值為100時結束循環。如果count的值能夠整除3,則跳出本次循環,不再執行下面的SELECT語句。
說明:LEAVE語句和ITERATE語句都用來跳出循環語句,但兩者的功能是不一樣的。
LEAVE語句是跳出整個循環,然後執行循環後面的程序。而ITERATE語句是跳出本次循環,然後進入下一次循環。
使用這兩個語句時一定要區分清楚。
6.REPEAT語句
REPEAT語句是有條件控制的循環語句。當滿足特定條件時,就會跳出循環語句。REPEAT語句的基本語法形式如下:
[begin_label:] REPEAT statement_list UNTIL search_condition END REPEAT [end_label]
其中,statement_list參數表示循環的執行語句;search_condition參數表示結束循環的條件,滿足該條件時循環結束。
下面是一個ITERATE語句的示例。代碼如下:
REPEAT SET @count=@count+1; UNTIL @count=100 END REPEAT ;
該示例循環執行count加1的操作,count值為100時結束循環。
REPEAT循環都用END REPEAT結束。
7.WHILE語句
WHILE語句也是有條件控制的循環語句。但WHILE語句和REPEAT語句是不一樣的。
WHILE語句是當滿足條件時,執行循環內的語句。
WHILE語句的基本語法形式如下:
[begin_label:] WHILE search_condition DO statement_list END WHILE [end_label]
其中,search_condition參數表示循環執行的條件,滿足該條件時循環執行;
statement_list參數表示循環的執行語句。
下面是一個ITERATE語句的示例。代碼如下:
WHILE @count<100 DO SET @count=@count+1; END WHILE ;
該示例循環執行count加1的操作,count值小於100時執行循環。
如果count值等於100了,則跳出循環。WHILE循環需要使用END WHILE來結束。
MySQL存儲過程/存儲過程與自定義函數的區別