MySQL存儲過程簡介

1.      存儲過程簡介mysql

 

咱們經常使用的操做數據庫語言SQL語句在執行的時候須要要先編譯,而後執行,而存儲過程(Stored Procedure)是一組爲了完成特定功能的SQL語句集,經編譯後存儲在數據庫中,用戶經過指定存儲過程的名字並給定參數(若是該存儲過程帶有參數)來調用執行它。redis

一個存儲過程是一個可編程的函數,它在數據庫中建立並保存。它能夠有SQL語句和一些特殊的控制結構組成。當但願在不一樣的應用程序或平臺上執行相同的函數,或者封裝特定功能時,存儲過程是很是有用的。數據庫中的存儲過程能夠看作是對編程中面向對象方法的模擬。它容許控制數據的訪問方式。sql

存儲過程一般有如下優勢:數據庫

(1).存儲過程加強了SQL語言的功能和靈活性。存儲過程能夠用流控制語句編寫,有很強的靈活性,能夠完成複雜的判斷和較複雜的運算。express

(2).存儲過程容許標準組件是編程。存儲過程被建立後,能夠在程序中被屢次調用,而沒必要從新編寫該存儲過程的SQL語句。並且數據庫專業人員能夠隨時對存儲過程進行修改,對應用程序源代碼毫無影響。編程

(3).存儲過程能實現較快的執行速度。若是某一操做包含大量的Transaction-SQL代碼或分別被屢次執行,那麼存儲過程要比批處理的執行速度快不少。由於存儲過程是預編譯的。在首次運行一個存儲過程時查詢,優化器對其進行分析優化,而且給出最終被存儲在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次運行時都要進行編譯和優化,速度相對要慢一些。安全

(4).存儲過程能過減小網絡流量。針對同一個數據庫對象的操做(如查詢、修改),若是這一操做所涉及的Transaction-SQL語句被組織程存儲過程,那麼當在客戶計算機上調用該存儲過程時,網絡中傳送的只是該調用語句,從而大大增長了網絡流量並下降了網絡負載。網絡

(5).存儲過程可被做爲一種安全機制來充分利用。系統管理員經過執行某一存儲過程的權限進行限制,可以實現對相應的數據的訪問權限的限制,避免了非受權用戶對數據的訪問,保證了數據的安全。ide

 

2.      關於MySQL的存儲過程函數

存儲過程是數據庫存儲的一個重要的功能,可是MySQL5.0之前並不支持存儲過程,這使得MySQL在應用上大打折扣。好在MySQL 5.0終於開始已經支持存儲過程,這樣便可以大大提升數據庫的處理速度,同時也能夠提升數據庫編程的靈活性。

3.      MySQL存儲過程的建立

 

(1). 格式

MySQL存儲過程建立的格式:CREATE PROCEDURE 過程名 ([過程參數[,...]])
[
特性 ...] 過程體

這裏先舉個例子:
   

  1. mysql> DELIMITER //  

  2. mysql> CREATE PROCEDURE proc1(OUT s int)  

  3.     -> BEGIN 

  4.     -> SELECT COUNT(*) INTO s FROM user;  

  5.     -> END 

  6.     -> //  

  7. mysql> DELIMITER ; 

 

注:

1)這裏須要注意的是DELIMITER //DELIMITER ;兩句,DELIMITER是分割符的意思,由於MySQL默認以";"爲分隔符,若是咱們沒有聲明分割符,那麼編譯器會把存儲過程當成SQL語句進行處理,則存儲過程的編譯過程會報錯,因此要事先用DELIMITER關鍵字申明當前段分隔符,這樣MySQL纔會將";"當作存儲過程當中的代碼,不會執行這些代碼,用完了以後要把分隔符還原。

2)存儲過程根據須要可能會有輸入、輸出、輸入輸出參數,這裏有一個輸出參數s,類型是int型,若是有多個參數用","分割開。

3)過程體的開始與結束使用BEGINEND進行標識。

這樣,咱們的一個MySQL存儲過程就完成了,是否是很容易呢?看不懂也不要緊,接下來,咱們詳細的講解。

 

(2). 聲明分割符

 

其實,關於聲明分割符,上面的註解已經寫得很清楚,不須要多說,只是稍微要注意一點的是:若是是用MySQLAdministrator管理工具時,能夠直接建立,再也不須要聲明。

 

(3). 參數

MySQL存儲過程的參數用在存儲過程的定義,共有三種參數類型,IN,OUT,INOUT,形式如:

CREATE PROCEDURE([[IN |OUT |INOUT ] 參數名 數據類形...])

IN 輸入參數:表示該參數的值必須在調用存儲過程時指定,在存儲過程當中修改該參數的值不能被返回,爲默認值

OUT 輸出參數:該值可在存儲過程內部被改變,並可返回

INOUT 輸入輸出參數:調用時指定,而且可被改變和返回

. IN參數例子

建立:

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE demo_in_parameter(IN p_in int)  

  3. -> BEGIN   

  4. -> SELECT p_in;   

  5. -> SET p_in=2;   

  6. -> SELECT p_in;   

  7. -> END;   

  8. -> //  

  9. mysql > DELIMITER ; 


執行結果
:

  1. mysql > SET @p_in=1;  

  2. mysql > CALL demo_in_parameter(@p_in);  

  3. +------+  

  4. | p_in |  

  5. +------+  

  6. |   1  |   

  7. +------+  

  8.  

  9. +------+  

  10. | p_in |  

  11. +------+  

  12. |   2  |   

  13. +------+  

  14.  

  15. mysql> SELECT @p_in;  

  16. +-------+  

  17. | @p_in |  

  18. +-------+  

  19. |  1    |  

  20. +-------+  


以上能夠看出,
p_in雖然在存儲過程當中被修改,但並不影響@p_id的值

 

.OUT參數例子

建立:

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE demo_out_parameter(OUT p_out int)  

  3. -> BEGIN 

  4. -> SELECT p_out;  

  5. -> SET p_out=2;  

  6. -> SELECT p_out;  

  7. -> END;  

  8. -> //  

  9. mysql > DELIMITER ; 


執行結果
:

  1. mysql > SET @p_out=1;  

  2. mysql > CALL sp_demo_out_parameter(@p_out);  

  3. +-------+  

  4. | p_out |   

  5. +-------+  

  6. NULL  |   

  7. +-------+  

  8.  

  9. +-------+  

  10. | p_out |  

  11. +-------+  

  12. |   2   |   

  13. +-------+  

  14.  

  15. mysql> SELECT @p_out;  

  16. +-------+  

  17. | p_out |  

  18. +-------+  

  19. |   2   |  

  20. +-------+  


. INOUT參數例子

建立:

  1. mysql > DELIMITER //   

  2. mysql > CREATE PROCEDURE demo_inout_parameter(INOUT p_inout int)   

  3. -> BEGIN 

  4. -> SELECT p_inout;  

  5. -> SET p_inout=2;  

  6. -> SELECT p_inout;   

  7. -> END;  

  8. -> //   

  9. mysql > DELIMITER ; 

 

 

執行結果:

  1. mysql > SET @p_inout=1;  

  2. mysql > CALL demo_inout_parameter(@p_inout) ;  

  3. +---------+  

  4. | p_inout |  

  5. +---------+  

  6. |    1    |  

  7. +---------+  

  8.  

  9. +---------+  

  10. | p_inout |   

  11. +---------+  

  12. |    2    |  

  13. +---------+  

  14.  

  15. mysql > SELECT @p_inout;  

  16. +----------+  

  17. | @p_inout |   

  18. +----------+  

  19. |    2     |  

  20. +----------+ 


(4). 變量

. 變量定義

DECLARE variable_name [,variable_name...] datatype [DEFAULT value];

其中,datatypeMySQL的數據類型,如:int, float, date, varchar(length)

例如:

  1. DECLARE l_int int unsigned default 4000000;  

  2. DECLARE l_numeric number(8,2) DEFAULT 9.95;  

  3. DECLARE l_date date DEFAULT '1999-12-31';  

  4. DECLARE l_datetime datetime DEFAULT '1999-12-31 23:59:59';  

  5. DECLARE l_varchar varchar(255) DEFAULT 'This will not be padded';   

 

 

. 變量賦值

 SET 變量名 = 表達式值 [,variable_name = expression ...]

 

. 用戶變量

 

. MySQL客戶端使用用戶變量

  1. mysql > SELECT 'Hello World' into @x;  

  2. mysql > SELECT @x;  

  3. +-------------+  

  4. |   @x        |  

  5. +-------------+  

  6. Hello World |  

  7. +-------------+  

  8. mysql > SET @y='Goodbye Cruel World';  

  9. mysql > SELECT @y;  

  10. +---------------------+  

  11. |     @y              |  

  12. +---------------------+  

  13. | Goodbye Cruel World |  

  14. +---------------------+  

  15.  

  16. mysql > SET @z=1+2+3;  

  17. mysql > SELECT @z;  

  18. +------+  

  19. | @z   |  

  20. +------+  

  21. |  6   |  

  22. +------+  

ⅱ. 在存儲過程當中使用用戶變量

  1. mysql > CREATE PROCEDURE GreetWorld( ) SELECT CONCAT(@greeting,' World');  

  2. mysql > SET @greeting='Hello';  

  3. mysql > CALL GreetWorld( );  

  4. +----------------------------+  

  5. | CONCAT(@greeting,' World') |  

  6. +----------------------------+  

  7. |  Hello World               |  

  8. +----------------------------+  

 

. 在存儲過程間傳遞全局範圍的用戶變量

  1. mysql> CREATE PROCEDURE p1()   SET @last_procedure='p1';  

  2. mysql> CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_proc);  

  3. mysql> CALL p1( );  

  4. mysql> CALL p2( );  

  5. +-----------------------------------------------+  

  6. | CONCAT('Last procedure was ',@last_proc  |  

  7. +-----------------------------------------------+  

  8. Last procedure was p1                         |  

  9. +-----------------------------------------------+  

 

 

注意:

用戶變量名通常以@開頭

濫用用戶變量會致使程序難以理解及管理

 

(5). 註釋

 

MySQL存儲過程可以使用兩種風格的註釋

雙模槓:--

該風格通常用於單行註釋

c風格: 通常用於多行註釋

例如:

 

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE proc1 --name存儲過程名  

  3. -> (IN parameter1 INTEGER)   

  4. -> BEGIN   

  5. -> DECLARE variable1 CHAR(10);   

  6. -> IF parameter1 = 17 THEN   

  7. -> SET variable1 = 'birds';   

  8. -> ELSE 

  9. -> SET variable1 = 'beasts';   

  10. -> END IF;   

  11. -> INSERT INTO table1 VALUES (variable1);  

  12. -> END   

  13. -> //  

  14. mysql > DELIMITER ;  

 

4.      MySQL存儲過程的調用

call和你過程名以及一個括號,括號裏面根據須要,加入參數,參數包括輸入參數、輸出參數、輸入輸出參數。具體的調用方法能夠參看上面的例子。

5.      MySQL存儲過程的查詢

咱們像知道一個數據庫下面有那些表,咱們通常採用show tables;進行查看。那麼咱們要查看某個數據庫下面的存儲過程,是否也能夠採用呢?答案是,咱們能夠查看某個數據庫下面的存儲過程,可是是令一鍾方式。

咱們能夠用

select name from mysql.proc where db=’數據庫名’;

或者

select routine_name from information_schema.routines where routine_schema='數據庫名';

或者

show procedure status where db='數據庫';

進行查詢。

若是咱們想知道,某個存儲過程的詳細,那咱們又該怎麼作呢?是否是也能夠像操做表同樣用describe 表名進行查看呢?

答案是:咱們能夠查看存儲過程的詳細,可是須要用另外一種方法:

SHOW CREATE PROCEDURE 數據庫.存儲過程名;

就能夠查看當前存儲過程的詳細。

 

6.      MySQL存儲過程的修改

ALTER PROCEDURE

更改用CREATE PROCEDURE 創建的預先指定的存儲過程,其不會影響相關存儲過程或存儲功能。

 

7.      MySQL存儲過程的刪除

刪除一個存儲過程比較簡單,和刪除表同樣:

DROP PROCEDURE

MySQL的表格中刪除一個或多個存儲過程。

 

8.      MySQL存儲過程的控制語句

(1). 變量做用域

內部的變量在其做用域範圍內享有更高的優先權,當執行到end。變量時,內部變量消失,此時已經在其做用域外,變量再也不可見了,應爲在存儲
過程外不再能找到這個申明的變量,可是你能夠經過out參數或者將其值指派
給會話變量來保存其值。

 

 

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE proc3()  

  3.      -> begin 

  4.      -> declare x1 varchar(5) default 'outer';  

  5.      -> begin 

  6.      -> declare x1 varchar(5) default 'inner';  

  7.      -> select x1;  

  8.      -> end;  

  9.      -> select x1;  

  10.      -> end;  

  11.      -> //  

  12. mysql > DELIMITER ;  

 

 (2). 條件語句

. if-then -else語句

 

 

 

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE proc2(IN parameter int)  

  3.      -> begin 

  4.      -> declare var int;  

  5.      -> set var=parameter+1;  

  6.      -> if var=0 then 

  7.      -> insert into t values(17);  

  8.      -> end if;  

  9.      -> if parameter=0 then 

  10.      -> update t set s1=s1+1;  

  11.      -> else 

  12.      -> update t set s1=s1+2;  

  13.      -> end if;  

  14.      -> end;  

  15.      -> //  

  16. mysql > DELIMITER ;  


. case語句: 

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE proc3 (in parameter int)  

  3.      -> begin 

  4.      -> declare var int;  

  5.      -> set var=parameter+1;  

  6.      -> case var  

  7.      -> when 0 then   

  8.      -> insert into t values(17);  

  9.      -> when 1 then   

  10.      -> insert into t values(18);  

  11.      -> else   

  12.      -> insert into t values(19);  

  13.      -> end case;  

  14.      -> end;  

  15.      -> //  

  16. mysql > DELIMITER ; 

 

(3). 循環語句

. while ···· end while

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE proc4()  

  3.      -> begin 

  4.      -> declare var int;  

  5.      -> set var=0;  

  6.      -> while var<6 do  

  7.      -> insert into t values(var);  

  8.      -> set var=var+1;  

  9.      -> end while;  

  10.      -> end;  

  11.      -> //  

  12. mysql > DELIMITER ; 

 

 

. repeat···· end repeat

它在執行操做後檢查結果,而while則是執行前進行檢查。

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE proc5 ()  

  3.      -> begin   

  4.      -> declare v int;  

  5.      -> set v=0;  

  6.      -> repeat  

  7.      -> insert into t values(v);  

  8.      -> set v=v+1;  

  9.      -> until v>=5  

  10.      -> end repeat;  

  11.      -> end;  

  12.      -> //  

  13. mysql > DELIMITER ;  

 


. loop ·····end loop:

loop循環不須要初始條件,這點和while 循環類似,同時和repeat循環同樣不須要結束條件, leave語句的意義是離開循環。

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE proc6 ()  

  3.      -> begin 

  4.      -> declare v int;  

  5.      -> set v=0;  

  6.      -> LOOP_LABLE:loop  

  7.      -> insert into t values(v);  

  8.      -> set v=v+1;  

  9.      -> if v >=5 then 

  10.      -> leave LOOP_LABLE;  

  11.      -> end if;  

  12.      -> end loop;  

  13.      -> end;  

  14.      -> //  

  15. mysql > DELIMITER ;  

 

 

. LABLES 標號:

標號能夠用在begin repeat while 或者loop 語句前,語句標號只能在合法的語句前面使用。能夠跳出循環,使運行指令達到複合語句的最後一步。

 

(4). ITERATE迭代

. ITERATE:

經過引用複合語句的標號,來重新開始複合語句

  1. mysql > DELIMITER //  

  2. mysql > CREATE PROCEDURE proc10 ()  

  3.      -> begin 

  4.      -> declare v int;  

  5.      -> set v=0;  

  6.      -> LOOP_LABLE:loop  

  7.      -> if v=3 then   

  8.      -> set v=v+1;  

  9.      -> ITERATE LOOP_LABLE;  

  10.      -> end if;  

  11.      -> insert into t values(v);  

  12.      -> set v=v+1;  

  13.      -> if v>=5 then 

  14.      -> leave LOOP_LABLE;  

  15.      -> end if;  

  16.      -> end loop;  

  17.      -> end;  

  18.      -> //  

  19. mysql > DELIMITER ; 

相關文章
相關標籤/搜索