一般咱們經常使用的操做數據庫語言SQL語句在執行的時候是須要先編譯的,而後才執行,而存儲過程是一組爲完成特定功能的SQL語句集,通過編譯後存儲在數據庫中,用戶能夠經過指定存儲過程的名字並給定參數(若是存儲過程帶有參數的話)來調用並執行它。css
存儲過程是一個可編程的函數,在數據庫中建立並保存。它有SQL語句和一些特殊的控制結構組成。當須要在不一樣的應用程序或平臺上執行相同的函數,或者封裝特定功能時,存儲過程是很是有用的。前端
存儲過程的有點主要有一下幾點:
①存儲過程增長了SQL語言的功能和靈活性。存儲過程能夠用流控制語句編寫,有很強的靈活性,能夠完成複雜的判斷和較複雜的運算。
②存儲過程容許標準組件是編程。存儲過程被建立後,能夠在程序中被屢次調用,而不用去重複的編寫該存儲過程的SQL語句。並且還能夠隨時對存儲過程進行修改,對應用程序自己的源代碼並沒有影響。
③存儲過程能實現較快的執行速度。若是某一操做包含大量的Transaction-SQL代碼或分別被屢次執行,那麼存儲過程要比批處理的執行速度快不少。由於存儲過程是預編譯的。在首次運行一個存儲過程時查詢,優化器對其進行分析優化,而且給出最終被存儲在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次運行時都要進行編譯和優化,速度相對要慢一些。
④減小網絡流量。
⑤存儲過程可被做爲一種安全機制來充分利用。系統管理員經過執行某一存儲過程的權限進行限制,可以實現對相應的數據的訪問權限的限制,避免了非受權用戶對數據的訪問,保證了數據的安全。
相對於oracle數據庫來講,MySQL的存儲過程相對功能較弱,使用較少。由於MySQL在5.0之前並不支持存儲過程,這使得MySQL在應用上大打折扣。好在MySQL 5.0終於開始已經支持存儲過程,這樣便可以大大提升數據庫的處理速度,同時也能夠提升數據庫編程的靈活性。mysql
1.格式:CREATE PROCEDURE 過程名([[IN|OUT|INOUT] 參數名 數據類型[,[IN|OUT|INOUT] 參數名 數據類型…]]) [特性 …] 過程體sql
>DELIMITER ??
>CREATE PROCEDURE student_count(OUT c int) >BEGIN >SELECT COUNT(*) as c FROM students;
>END;
>??
>DELIMITER ;
注意:分隔符,MySQL默認以」;」爲分隔符,若是沒有聲明分割符,則編譯器會把存儲過程當成SQL語句進行處理,所以編譯過程會報錯,因此要事先用「DELIMITER //」聲明當前段分隔符,讓編譯器把兩個」//」之間的內容當作存儲過程的代碼,不會執行這些代碼;「DELIMITER ;」的意爲把分隔符還原。
參數,存儲過程根據須要可能會有輸入、輸出、輸入輸出參數,這裏有一個輸出參數c,類型是int型,若是有多個參數用」,」分割開。MySQL存儲過程的參數用在存儲過程的定義,共有三種參數類型,IN,OUT,INOUT:IN參數的值必須在調用存儲過程時指定,在存儲過程當中修改該參數的值不能被返回,爲默認值;OUT:該值可在存儲過程內部被改變,並可返回;INOUT:調用時指定,而且可被改變和返回。
過程體,過程體的開始與結束使用BEGIN與END進行標識。數據庫
例:建立一個存儲過程,查詢指定店鋪今日糉子賣出量、剩餘量編程
> delimiter $$
> CREATE PROCEDURE get_info(IN shopNo int) > BEGIN >select remaining_cout,sold_cout from shop_goods where shop_id=shopNo;
> END;
>$$
> delimiter ; #將語句的結束符號恢復爲分號
>call get_info(618); //調用定義好的存儲過程
說明:在實際開發中,做爲普通開發人員,應該(至少我不會去終端鏈接數據庫,操做數據庫)不多會去這樣操做。應該是在使用的數據庫管理工具中去操做的,好比:Navicat數據庫管理工具。下面就來具體操做一把。後端
打開數據庫管理工具,選擇要建立存儲過程的數據庫,而後選擇‘Functions’這個菜單,界面如上圖所示 ,存儲過程寫好以後,若是要傳入參數或者輸出,點擊‘Parameter’右邊的‘···’彈窗如上圖,輸入參數名,而後選擇參數類型,長度以及最後的Model,Model有三個值:IN、OUT、INTOUT,這三個值在上面已經說明了。添加多個參數,點擊‘+’便可,若是要刪除參數,選中要刪除的參數,而後點擊‘-’便可刪除。
安全
最後,也是最重要的一步就是不要忘了點擊保存。
而後在‘Functions’下就能夠看到定義好的存儲過程了。
調用存儲過程
代碼中調用存儲過程:(TP5框架+PHP)網絡
//定義函數,在須要用到此函數的地方調用函數時,就會調用到存儲過程了。
function test() {
$author_id = $this->requst->param('author_id'); //獲取參數
$info = db()->query("call get_author_info($author_id)"); //$info中就是調用存儲過程,返回的數據信息
...
}
若是想要查一下,當前數據庫中一共建立了哪些存儲過程的話,可像下面這樣去查。oracle
SHOW PROCEDURE STATUS WHERE db='article'; //article是數據庫名稱
SELECT name FROM mysql.proc WHERE db='article';
select routine_name from information_schema.routines where routine_schema='article';
若是想要查看某一個存儲過程的詳細,能夠經過下面的方法查看。
SHOW PROCEDURE STATUS WHERE db='article';
SHOW CREATE PROCEDURE article.get_author_info;
//兩種發放均可以,只不過返回的值不同,詳細程度不一樣
ALTER PROCEDURE
更改用CREATE PROCEDURE 創建的預先指定的存儲過程,其不會影響相關存儲過程或存儲功能。
刪除一個存儲過程比較簡單,和刪除表同樣:
DROP PROCEDURE 從MySQL的表格中刪除一個或多個存儲過程。
例:
> DELIMITER //
> CREATE PROCEDURE proc3 (in parameter int) > begin > declare var int;
> set var=parameter+1;
> case var
> when 0 then
> insert into t values(17);
> when 1 then
> insert into t values(18);
> else
> insert into t values(19);
> end case;
> end;
> //
> DELIMITER ;
①字符串類 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 ②數字類 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爲小數位數] ③日期類 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) //開平方