MySql中的存儲過程

先上一個存儲過程:

 DELIMITER //
drop procedure if exists log_system; 
CREATE PROCEDURE log_system (in s INT)
BEGIN
 set s=(SELECT userLoggingNumber FROM logging_prameter);
 SELECT * FROM user_logging ORDER BY time LIMIT s;
END;
//DELIMITER

CALL log_system(@a);



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

這裏先舉個例子:

DELIMITER //  
CREATE PROCEDURE proc1 (OUT s INT)
BEGIN
	SELECT
		COUNT(*) INTO s
	FROM
		USER ;
	END//  
DELIMITER ; 

注:

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

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

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

 聲明分割符

 

其實,關於聲明分割符,上面的註解已經寫得很清楚,不需要多說,只是稍微要注意一點的是:如果是用MySQLAdministrator管理工具時,可以直接創建,不再需要聲明。

 

參數

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

CREATEPROCEDURE([[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存儲過程的查詢

我們像知道一個數據庫下面有那些表,我們一般採用showtables;進行查看。那麼我們要查看某個數據庫下面的存儲過程,是否也可以採用呢?答案是,我們可以查看某個數據庫下面的存儲過程,但是是令一鍾方式。

我們可以用

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

或者

selectroutine_name from information_schema.routines whereroutine_schema='數據庫名';

或者

show procedurestatus where db='數據庫';

進行查詢。

如果我們想知道,某個存儲過程的詳細,那我們又該怎麼做呢?是不是也可以像操作表一樣用describe表名進行查看呢?

答案是:我們可以查看存儲過程的詳細,但是需要用另一種方法:

SHOW CREATEPROCEDURE數據庫.存儲過程名;

就可以查看當前存儲過程的詳細。

 

6.     MySQL存儲過程的修改

ALTER PROCEDURE

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

 

7.     MySQL存儲過程的刪除

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

DROPPROCEDURE

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 ···· endwhile

  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···· endrepeat

它在執行操作後檢查結果,而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 ·····endloop:

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 ; 

 

 

9.     MySQL存儲過程的基本函數

 

(1).字符串類

CHARSET(str) //返回字串字符集
CONCAT (string2 [,... ])//
連接字串
INSTR (string ,substring )//
返回substring首次在string中出現的位置,不存在返回0
LCASE (string2 ) //
轉換成小寫

LEFT (string2 ,length )//
string2中的左邊起取length個字符
LENGTH (string )//string
長度
LOAD_FILE (file_name )//
從文件讀取內容
LOCATE (substring , string[,start_position ] )
INSTR,但可指定開始位置
LPAD (string2 ,length ,pad )//
重複用pad加在string開頭,直到字串長度爲length
LTRIM (string2 ) //
去除前端空格

REPEAT (string2 ,count )//
重複count
REPLACE (str ,search_str,replace_str ) //
str中用replace_str替換search_str
RPAD (string2 ,length ,pad) //
str後用pad補充,直到長度爲
length
RTRIM (string2 ) //
去除後端空格

STRCMP (string1 ,string2 )//
逐字符比較兩字串大小,
SUBSTRING (str , position [,length ]) //
strposition開始,length個字符
,
注:mysql中處理字符串時,默認第一個字符下標爲1,即參數position必須大於等於1
 

 

  1. mysql> select substring('abcd',0,2); 
  2. +-----------------------+ 
  3. substring('abcd',0,2) | 
  4. +-----------------------+ 
  5. |                       | 
  6. +-----------------------+ 
  7. 1 row in set (0.00 sec) 
  8.  
  9. mysql> select substring('abcd',1,2); 
  10. +-----------------------+ 
  11. substring('abcd',1,2) | 
  12. +-----------------------+ 
  13. |     ab                | 
  14. +-----------------------+ 
  15. 1 row in set (0.02 sec) 

TRIM([[BOTH|LEADING|TRAILING] [padding]FROM]string2) //去除指定位置的指定字符
UCASE (string2 )//
轉換成大寫
RIGHT(string2,length)//
string2最後length個字符
SPACE(count)//
生成count個空格

(2).數學類

ABS (number2 ) //絕對值
BIN (decimal_number )//
十進制轉二進制
CEILING (number2 )//
向上取整
CONV(number2,from_base,to_base) //
進制轉換
FLOOR (number2 )//
向下取整
FORMAT (number,decimal_places) //
保留小數位數
HEX (DecimalNumber )//
轉十六進制
注:HEX()中可傳入字符串,則返回其ASC-11,如HEX('DEF')返回4142143
也可以傳入十進制整數,返回其十六進制編碼,如HEX(25)返回
19
LEAST (number , number2 [,..]) //
求最小值

MOD (numerator ,denominator )//
求餘
POWER (number ,power )//
求指數
RAND([seed])//
隨機數
ROUND (number [,decimals ])//
四捨五入,decimals爲小數位數]

注:返回類型並非均爲整數,如:
(1)
默認變爲整形值

  1. mysql> select round(1.23); 
  2. +-------------+ 
  3. | round(1.23) | 
  4. +-------------+ 
  5. |           1 | 
  6. +-------------+ 
  7. 1 row in set (0.00 sec) 
  8.  
  9. mysql> select round(1.56); 
  10. +-------------+ 
  11. | round(1.56) | 
  12. +-------------+ 
  13. |           2 | 
  14. +-------------+ 
  15. 1 row in set (0.00 sec) 



(2)
可以設定小數位數,返回浮點型數據

  1. mysql> select round(1.567,2); 
  2. +----------------+ 
  3. | round(1.567,2) | 
  4. +----------------+ 
  5. |           1.57 | 
  6. +----------------+ 
  7. 1 row in set (0.00 sec) 

SIGN (number2 ) //

 

(3).日期時間類

ADDTIME (date2 ,time_interval ) //time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //
轉換時區
CURRENT_DATE ( ) //
當前日期
CURRENT_TIME ( ) //
當前時間
CURRENT_TIMESTAMP ( ) //
當前時間戳
DATE (datetime ) //
返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //
date2中加上日期或時間
DATE_FORMAT (datetime ,FormatCodes ) //
使用formatcodes格式顯示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //
date2上減去一個時間
DATEDIFF (date1 ,date2 ) //
兩個日期差
DAY (date ) //
返回日期的天
DAYNAME (date ) //
英文星期
DAYOFWEEK (date ) //
星期(1-7) ,1爲星期天
DAYOFYEAR (date ) //
一年中的第幾天
EXTRACT (interval_name FROM date ) //
date中提取日期的指定部分
MAKEDATE (year ,day ) //
給出年及年中的第幾天,生成日期串
MAKETIME (hour ,minute ,second ) //
生成時間串
MONTHNAME (date ) //
英文月份名
NOW ( ) //
當前時間
SEC_TO_TIME (seconds ) //
秒數轉成時間
STR_TO_DATE (string ,format ) //
字串轉成時間,format格式顯示
TIMEDIFF (datetime1 ,datetime2 ) //
兩個時間差
TIME_TO_SEC (time ) //
時間轉秒數]
WEEK (date_time [,start_of_week ]) //
第幾周
YEAR (datetime ) //
年份
DAYOFMONTH(datetime) //
月的第幾天
HOUR(datetime) //
小時
LAST_DAY(date) //date
的月的最後日期
MICROSECOND(datetime) //
微秒
MONTH(datetime) //

MINUTE(datetime) //
返回符號,正負或0
SQRT(number2) //
開平方

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章