MySQL儲存過程詳解 mysql 儲存過程
mysql儲存過程詳解
1. 儲存過程簡介
我們常用的運算元據庫語言SQL語句在執行的時候需要要先編譯,然後執行,而儲存過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯後儲存在資料庫中,使用者透過指定儲存過程的名字並給定引數(如果該儲存過程帶有引數)來呼叫執行它。
一個儲存過程是一個可程式設計的函式,它在資料庫中建立並儲存。它可以有SQL語句和一些特殊的控制結構組成。當希望在不同的應用程式或平臺上執行相同的函式,或者封裝特定功能時,儲存過程是非常有用的。資料庫中的儲存過程可以看做是對程式設計中物件導向方法的模擬。它允許控制資料的訪問方式。
儲存過程通常有以下優點:
(1).儲存過程增強了SQL語言的功能和靈活性。儲存過程可以用流控制語句編寫,有很強的靈活性,可以完成複雜的判斷和較複雜的運算。
(2).儲存過程允許標準元件是程式設計。儲存過程被建立後,可以在程式中被多次呼叫,而不必重新編寫該儲存過程的SQL語句。而且資料庫專業人員可以隨時對儲存過程進行修改,對應用程式原始碼毫無影響。
(3).儲存過程能實現較快的執行速度。如果某一操作包含大量的Transaction-SQL程式碼或分別被多次執行,那麼儲存過程要比批處理的執行速度快很多。因為儲存過程是預編譯的。在首次執行一個儲存過程時查詢,最佳化器對其進行分析最佳化,並且給出最終被儲存在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次執行時都要進行編譯和最佳化,速度相對要慢一些。
(4).儲存過程能過減少網路流量。針對同一個資料庫物件的操作(如查詢、修改),如果這一操作所涉及的Transaction-SQL語句被組織程儲存過程,那麼當在客戶計算機上呼叫該儲存過程時,網路中傳送的只是該呼叫語句,從而大大增加了網路流量並降低了網路負載。
(5).儲存過程可被作為一種安全機制來充分利用。系統管理員透過執行某一儲存過程的許可權進行限制,能夠實現對相應的資料的訪問許可權的限制,避免了非授權使用者對資料的訪問,保證了資料的安全。
2. 關於MySQL的儲存過程
儲存過程是資料庫儲存的一個重要的功能,但是MySQL在5.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)過程體的開始與結束使用BEGIN與END進行標識。
這樣,我們的一個MySQL儲存過程就完成了,是不是很容易呢?看不懂也沒關係,接下來,我們詳細的講解。
(2). 宣告分割
其實,關於宣告分割符,上面的註解已經寫得很清楚,不需要多說,只是稍微要注意一點的是:如果是用MySQL的Administrator管理工具時,可以直接建立,不再需要宣告。
(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];
其中,datatype為MySQL的資料型別,如: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 ;
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 ]) //從str的position開始,取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) //開平方
1. 儲存過程簡介
我們常用的運算元據庫語言SQL語句在執行的時候需要要先編譯,然後執行,而儲存過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯後儲存在資料庫中,使用者透過指定儲存過程的名字並給定引數(如果該儲存過程帶有引數)來呼叫執行它。
一個儲存過程是一個可程式設計的函式,它在資料庫中建立並儲存。它可以有SQL語句和一些特殊的控制結構組成。當希望在不同的應用程式或平臺上執行相同的函式,或者封裝特定功能時,儲存過程是非常有用的。資料庫中的儲存過程可以看做是對程式設計中物件導向方法的模擬。它允許控制資料的訪問方式。
儲存過程通常有以下優點:
(1).儲存過程增強了SQL語言的功能和靈活性。儲存過程可以用流控制語句編寫,有很強的靈活性,可以完成複雜的判斷和較複雜的運算。
(2).儲存過程允許標準元件是程式設計。儲存過程被建立後,可以在程式中被多次呼叫,而不必重新編寫該儲存過程的SQL語句。而且資料庫專業人員可以隨時對儲存過程進行修改,對應用程式原始碼毫無影響。
(3).儲存過程能實現較快的執行速度。如果某一操作包含大量的Transaction-SQL程式碼或分別被多次執行,那麼儲存過程要比批處理的執行速度快很多。因為儲存過程是預編譯的。在首次執行一個儲存過程時查詢,最佳化器對其進行分析最佳化,並且給出最終被儲存在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次執行時都要進行編譯和最佳化,速度相對要慢一些。
(4).儲存過程能過減少網路流量。針對同一個資料庫物件的操作(如查詢、修改),如果這一操作所涉及的Transaction-SQL語句被組織程儲存過程,那麼當在客戶計算機上呼叫該儲存過程時,網路中傳送的只是該呼叫語句,從而大大增加了網路流量並降低了網路負載。
(5).儲存過程可被作為一種安全機制來充分利用。系統管理員透過執行某一儲存過程的許可權進行限制,能夠實現對相應的資料的訪問許可權的限制,避免了非授權使用者對資料的訪問,保證了資料的安全。
2. 關於MySQL的儲存過程
儲存過程是資料庫儲存的一個重要的功能,但是MySQL在5.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)過程體的開始與結束使用BEGIN與END進行標識。
這樣,我們的一個MySQL儲存過程就完成了,是不是很容易呢?看不懂也沒關係,接下來,我們詳細的講解。
(2). 宣告分割
其實,關於宣告分割符,上面的註解已經寫得很清楚,不需要多說,只是稍微要注意一點的是:如果是用MySQL的Administrator管理工具時,可以直接建立,不再需要宣告。
(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];
其中,datatype為MySQL的資料型別,如: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 ;
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 ]) //從str的position開始,取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) //開平方
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/20200170/viewspace-2122553/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL儲存過程詳解 mysql 儲存過程linkMySql儲存過程
- mysql儲存過程詳解MySql儲存過程
- mysql 儲存過程MySql儲存過程
- MySql儲存過程—2、第一個MySql儲存過程的建立MySql儲存過程
- mysql儲存過程整理MySql儲存過程
- MySQL之儲存過程MySql儲存過程
- [MYSQL -23儲存過程]MySql儲存過程
- MYSQL儲存過程管理MySql儲存過程
- mysql儲存過程例子MySql儲存過程
- mysql的儲存過程MySql儲存過程
- MySQL---------儲存過程MySql儲存過程
- 【Mysql】Mysql儲存過程學習MySql儲存過程
- mysql儲存過程經典例項詳解MySql儲存過程
- mysql如何呼叫儲存過程MySql儲存過程
- Mysql 儲存過程的使用MySql儲存過程
- mysql儲存過程案例解析MySql儲存過程
- mysql儲存過程的修改MySql儲存過程
- MySQL儲存過程SAVEPOINT ROLLBACK toMySql儲存過程
- Mysql 的儲存過程和儲存函式MySql儲存過程儲存函式
- mysql 儲存過程和事件排程MySql儲存過程事件
- mongo 儲存過程詳解Go儲存過程
- 儲存過程的詳解儲存過程
- Laravel 中使用 MySQL 儲存過程LaravelMySql儲存過程
- MySQL 儲存過程和函式MySql儲存過程函式
- mysql儲存過程的引數MySql儲存過程
- MySql資料庫——儲存過程MySql資料庫儲存過程
- MySQL儲存過程 (即函式)MySql儲存過程函式
- MySQL儲存過程和函式MySql儲存過程函式
- mysql 遊標的使用(儲存過程)MySql儲存過程
- MySQL 建立儲存過程報錯MySql儲存過程
- mysql儲存過程小試牛刀MySql儲存過程
- 用PHP呼叫MySQL儲存過程PHPMySql儲存過程
- mysql儲存過程宣告順序MySql儲存過程
- c / c + + 呼叫mysql儲存過程MySql儲存過程
- mysql儲存過程一例MySql儲存過程
- mySql 儲存過程與函式MySql儲存過程函式
- mysql和orcale的儲存過程和儲存函式MySql儲存過程儲存函式
- Mysql 5.7儲存過程的學習MySql儲存過程