2013-09-23 23:44:58| 分類: MySQL基礎篇 | 標籤:mysql存儲過程和函數 |舉報 |字號 訂閱
本來想說些關於這個前奏,快晚上12點了。直接上正題吧!mysql存儲過程和函數示例
v
字體說明: 紅色字體爲需要強調的。藍色字體爲MySQL關鍵字。綠色字體爲解釋性說明文字。
另,圖片裏面的標註和紅色字體解釋也很重要。
1. 創建存儲過程
語法:
CREATE PROCEDURE sp_name ( [ proc_parameter ] )
[ characteristics ... ] routune_body
說明: proc_parameter 的形式有: [
IN | OUT |
INOUT ] paramP_name type .
routune_body 爲SQL語句組成。
例: 創建一個名稱爲AvgPrice的存儲過程,返回所有產品的平均價格。如下:
/* 此存儲過程雖然沒有參數。但是後面的 ()
還是得要加上 */
CREATE PROCEDURE AvgPrice ()
BEGIN
SELECT AVG(price) AS avgPrice
FROM product;
END;
注意: DELIMITER 的用法。
如圖:
例: 創建一個名爲CountProc的存儲過程,帶有輸出參數。
CREATE PROCEDURE CountProc( OUT param1 INT )
BEGIN
SELECT COUNT(*) INTO param1 FROM product;
END;
如圖:
注意: 使用DELIMITER命令時候,應該避免使用反斜槓(‘ \ ’)字符,因爲反斜槓是轉義字符。
2. 創建函數
語法:
CREATE FUNCTION func_name ( [ func_parameter ] )
RETURNS type
[ characteristic ... ] routine_body
說明: func_name 爲函數名稱;func_parameter 的形式有:
[ IN |
OUT | INOUT ] paramP_name type .
RETURNS type 語句表示函數的返回數據的類型。
例:創建存儲函數,名稱爲TestFunc1. 返回id爲 1 的產品名稱。
CREATE FUNCTION TestFunc1()
RETURNS VARCHAR(30)
RETURN ( SELECT prodname FROM product WHERE id='1' );
如圖:
3. 變量的使用
3.1 定義變量
語法:
DECLARE var_name [ ,varname ] ... data_type [ DEFAULT value ] ;
例: 定義名稱爲p1的變量,數據類型爲INT,默認值爲 100。如下:
DECLARE p1 INT DEFAULT 100 ;
3.2 爲變量賦值
語法:
SET var_name = expr [ , var_name = expr ] ... ;
例: 聲明3個變量var1、 var2、var3,數據類型爲INT,使用SET賦值。如下:
DECLARE var1 , var2 , var3 INT ;
SET var1 = 10, var2 = 20;
SET var3 = var1 + var2 ;
例:使用 SELECT ... INTO 賦值。如下:
DECLARE name VARCHAR(20) ;
DECLARE prodprice DECIMAL( 8 ,2 );
SELECT prodname , price INTO name , prodprice FROM product WHERE id = '1' ;
4. 定義條件和處理程序
4.1 定義條件
語法:
DELCARE condition_name
CONDITION FOR [ condition_type ]
其中 [ condition_type ] :
SQLSTATE [ VALUE ] sqlstate_vlaue | mysql_error_code
例: 定義 “ERRROR 1148(42000)”錯誤。名稱爲command_not_allowed。用兩種方式定義:
//方法一: 使用sqlstate_value
DECLARE command_not_allowed CONDITION FROM SQLSTATE '42000' ;
//方法二:使用mysql_error_code
DECLARE command_not_allowed CONDITION FOR 1148;
4.2 定義處理程序
語法:
DECLARE handler_type
HANDLER FOR condition_value [ , ... ] sp_statement
其中 handler_type 形式如下:
CONTINUE | EXIT | UNDO
其中 condition_value 形式如下:
SQLSTATE[ VALUE ] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
| mysql_error_code
說明:
handler_type 爲處理方式,參數取值有3個值:
CONTINUE (表示遇到錯誤不處理,繼續執行);
EXIT(表示遇到錯馬上就退出);
UNDO(表示遇到錯誤就撤回之前的操作,MySQL5.5還不支持)。
condition_value 表示錯誤類型,可以取值有:
SQLSTATE[ VALUE ] sqlstate_value 包含5個字符的字符串錯誤值;
condition_name表示 DECLARE CONDITION 定義的錯誤條件名稱;
SQLWARNING 匹配所有以 01 開頭的SQLSTATE錯誤代碼;
NOT FOUND 匹配所有以 02 開頭的SQLSTATE錯誤代碼;
SQLEXCEPTION 匹配所有沒有被SQLWARNING 和或者NOT FOUND 捕獲的
SQLSTATE錯誤代碼;
例:定義處理程序。如下:
// 方法一:捕獲sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info = 'NO_SUCH_TABLE';
//方法二: 捕獲mysql_error_code
DECLARE CONTINUE HANDLER FOR 1146 SET @info = 'NO_SUCH_TABLE';
//方法三:先定義條件,然後調用
DECLARE no_such_table CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info = 'NO_SUCH_TABLE';
//方法四:使用 SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info = 'ERROR';
//方法五:使用 NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info = 'NO_SUCH_TABLE';
//方法六:使用 SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = 'ERROR';
例:定義條件和處理程序,具體執行如下:
CREATE TABLE t7( s1 int ,primary key(s1) );
CREATE PROCEDURE testhandler()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1 ;
SET @X = 1;
INSERT INTO t7 VALUES(1);
SET @x = 2;
INSERT INTO t7 VALUES(1);
SET @x = 3;
END ;
CALL testhandler();
SELECT @x;
如圖:
在本例中,將 DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1 ;去掉
查看返回情況:
5. 遊標的使用
遊標只能在存儲過程和函數中使用。
5.1 聲明遊標
語法:
DECLARE cursor_name CURSOR FOR
select_statement
5.2 打開遊標
語法:
OPEN cursor_name{遊標名稱}
5.3 使用遊標
語法:
FETCH cursor_name
INTO var_name [ , var_name ]...{參數名稱}
5.4 關閉遊標
語法:
CLOSE cursor_name{遊標名稱};
6. 流程控制語句
6.1 IF 語句
語法:
IF expr_condtion THEN
statement_list
[ ELSEIF expr_condition
THEN statement_list ] ...
[ ELSE statement_list ]
END IF
例:IF語句例子。如下:
IF val IS NULL
THEN SELECT 'val is NULL'
ELSEIF SELECT 'val is not NULL'
END IF ;
6.2 CASE語句
語法:
CASE case_expr
WHEN when_value THEN
statement_list
[ WHEN when_value
THEN statement ] ....
[ WHEN statement_list ]
END CASE
或者
CASE
WHEN expr_condition THEN
statement_list
[ WHEN
expr_condition THEN statement_list ] ....
[ WHEN statement_list ]
END CASE
例:CASE 語句示例。如下:
CASE val
WHEN 1 THEN SELECT 'val is 1';
WHEN 2 THEN SELECT 'val is 2';
ELSE SELECT 'val is not 1 or 2 ';
END CASE;
例:CASE語句的另一種形式。如下:
CASE
WHEN val IS NULL THEN SELECT 'val is NULL';
WHEN val < 0 THEN SELECT 'val is less than 0;
WHEN val > 0 THEN SELECT 'val is greater than 0';
END CASE;
6.3 LOOP 語句
語法:
[ loop_lable : ] LOOP
statement_list
END LOOP [loop_lable]
例:使用LOOP進行循環操作,id值小於10等於之前,將重複執行循環過程。如下:
DECLARE id INT DEFAULT 0;
add_loop: LOOP
SET id = id + 1;
IF id >= 10 THEN LEAVE add_loop;
END IF;
END LOOP add_loop;
6.4 LEAVE 語句
LEAVE 語句用來退出任何被標註的流程控制構造。
語法:
LEAVE lable
例: 使用LEAVE 語句退出循環。如下:
add_num : LOOP
SET @count = @count + 1;
IF @count = 50 THEN LEAVE add_num;
END IF;
END LOOP add_num;
6.5 ITERATE 語句
ITERATE 語句將執行順序轉到語句段開頭出,相當於java中的continue。
語法:
ITERATE lable ;
例:如果p1的值小於10時,重複執行p1加1操作;當p1大於等於10且小於20 的時候打印
消息“p1 is between 10 an 20”;當p1大於20時,退出循環。如下:
CREATE PROCEDURE doiterate()
BEGIN
DECLARE p1 INT DEFAULT 0;
my_loop : LOOP
SET p1 = p1 +1;
IF p1 < 10 THEN ITERATE my_loop;
ELSEIF p1 > 20 THEN LEAVE my_loop;
END IF;
SELECT 'p1 is between 10 an 20' AS msg;
END LOOP my_loop;
END;
如圖:
6.6 REPEAT 語句
REPEAT 語句創建一個帶有條件判斷的循環過程,每次語句執行完畢後,會對條件表達式進行判斷,如果
表達式爲真,則循環結束;否則重複執行循環體中的語句。
語法:
[repeat_lable : ] REPEAT
statement_list
UNTIL expr_condition
END REPEAT [ repeat_lable ]
例:id值小於等於10之前,將重複執行循環過程。如下:
DECLARE id INT DEFAULT 0;
REPEAT
SET id = id +1;
UNTIL id > 10 ;
END REPEAT ;
7. 調用存儲過程和函數
調用存儲過程用關鍵字CALL。 調用函數時,直接在語句中使用。 由於這個叫簡單。略。
8. 查看存儲過程和函數
8.1 SHOW STATUS 語句查看存儲過程和函數的狀態。
語法:
SHOW { PROCEDURE
| FUNCTION } STATUS
[ LIKE 'pattern' ]; 其中 LIKE 語句表示匹配的
存儲過程或者函數的名稱。
例:獲取以 ‘do’ 開頭的存儲過程的狀態。如下:
8.2 SHOW CREATE 語句查看存儲過程和函數的定義。
語法:
SHOW CREATE { PROCEDURE
| FUNCTION } sp_name
例: 查看存儲過程doiterate的定義。如下:
9. 刪除存儲過程和函數
語法:
DROP { PROCEDURE | FUNCTION } [ IF EXISTS
] sp_name;
======================END=======================
由於前幾晚上都快凌晨一點才睡,喫不消啊。今晚的11點準時睡覺啦。 加油!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.