SQL語句須要先編輯後執行,而存儲過程是一組爲了完成特定功能的SQL語句集,經編譯後存儲過程在數據庫中,用戶經過制定存儲過程的名字並傳給參數來調用它。前端
存儲過程是可編程的函數,在數據庫中建立並保持,能夠由SQL和控制結構組成。檔想要在不一樣的應用平臺上執行相同的函數,或者封裝特定功能時,存儲過程是很是有用的,數據庫中的存儲過程能夠看錯是對編程面向對象方法的模擬,它容許控制數據的訪問方式。mysql
存儲過程的優勢:sql
1.加強SQL語言的功能和靈活性:存儲過程能夠用編程語句編寫,有很強的靈活性,能夠完成複雜的判斷和較複雜得運算。數據庫
2.標準組建式編程:存儲過程被建立後,能夠在程序中被屢次調用,而沒必要從新編寫該存儲過程的SQL語句。並且數據庫專業人員能夠隨時對數據庫存儲過程進行修改,對應用程序源代碼毫無影響。編程
3.較快的執行速度:若是某一操做包含大量的transaction-SQL代碼或分別被屢次執行,那麼存儲過程要比批處理的執行速度快不少。由於存儲過程是預編譯的。在首次運行一個存儲過程時查詢,優化器對其進行分析優化,並且給出最終被存儲在系統表中的執行變化。2、批處理的transaction-SQL語句在每次運行時都要進行編譯和優化,速度相對慢一些。後端
4.減小網絡流量:安全
針對同一數據庫對象若是這一操做所涉及的transaction-SQL語句被組織進存儲過程,那麼當客戶計算機在調用存儲過程時,網絡中傳送的只是該調用語句,從而大大減小網絡流量並下降了網絡負載。網絡
5.做爲一種安全機制來充分利用:經過對執行某一存儲過程的權限進行限制,能可以實現對相應數據的訪問權限的限制,避免了飛受權用戶對數據的訪問,保證了數據的安全。函數
***********************************************************************oop
自定義函數
1.函數必須指定返回值,並且參數默認IN類型
2.存儲過程沒有返回值,參數能夠是IN、OUT、IN OUT類型,有的人可能會理解成out也算是返回值。
3.調用方式:函數select my_fun();過程call my_pro();
mysql存儲過程和函數的區別
1.存儲過程實現的功能要複雜一點,函數實現功能針對性比較強。存儲過程功能強大,能夠執行包括修改表等一系列數據庫操做;用戶定義函數不能用於執行一組修改全局數據庫狀態的操做。
2.對於存儲過程來講能夠返回參數,如記錄集,函數只能返回值或者表對象。函數存儲過程的參數有IN、out、in out 三種,而函數只有in類;
存儲過程聲明時不須要返回類型,而函數聲明時須要描述返回類型,且函數體中必須包含一個有效的return語句。
3.存儲過程可使用非肯定函數,不容許在用戶定義函數主體中內置非肯定函數。
4.存儲過程通常是做爲一個獨立的部分來執行(EXECUTE語句執行),而函數能夠做爲查詢語句的一部分來調用(select調用)。
因爲函數能夠返回一個表對象,所以它能夠在查詢語句中位於from關鍵字的後面。sql語句中不可用存儲過程,而可使用函數。
**************************************************************
MySQL存儲過程的建立
語法
CREATE PROCEDURE 過程名([[IN|OUT|INOUT] 參數名 數據類型[,[IN|OUT|INOUT] 參數名 數據類型…]]) [特性 ...] 過程體
DELIMITER // CREATE PROCEDURE myproc(OUT s int) BEGIN SELECT COUNT(*) INTO s FROM students; END // DELIMITER ;
IN參數的值必須在調用存儲過程時指定,在存儲過程當中修改該參數的值不能被返回,爲默認值
OUT:該值可在存儲過程內部被改變,並可返回
INOUT:調用時指定,而且可被改變和返回
數據類型
日期和時間類型
字符串類型
#在MySQL客戶端使用用戶變量 SELECT 'Hello World' into @x; SELECT @x; SET @y='Goodbye Cruel World'; SELECT @y; SET @z=1+2+3; SELECT @z; #在存儲過程當中使用用戶變量 CREATE PROCEDURE GreetWorld() SELECT CONCAT(@greeting,' World'); SET @greeting='Hello'; CALL GreetWorld(); #在存儲過程間傳遞全局範圍的用戶變量 CREATE PROCEDURE p1() SET @last_proc='p1'; CREATE PROCEDURE p2() SELECT CONCAT('Last procedure was ',@last_proc); CALL p1(); CALL p2();
註釋
MySQL存儲過程可以使用兩種風格的註釋:
雙槓:--,該風格通常用於單行註釋
C風格: 通常用於多行註釋
mysql存儲過程的調用
用call和你過程名以及一個括號,括號裏面根據須要,加入參數,參數包括輸入參數、輸出參數、輸入輸出參數。
MySQL存儲過程的查詢
#查詢存儲過程 SELECT name FROM mysql.proc WHERE db='數據庫名'; SELECT routine_name FROM information_schema.routines WHERE routine_schema='數據庫名'; SHOW PROCEDURE STATUS WHERE db='數據庫名'; #查看存儲過程詳細信息 SHOW CREATE PROCEDURE 數據庫.存儲過程名;
MySQL存儲過程的修改
ALTER PROCEDURE 更改用CREATE PROCEDURE 創建的預先指定的存儲過程,其不會影響相關存儲過程或存儲功能。
MySQL存儲過程的刪除
DROP PROCEDURE [過程1[,過程2…]]
從MySQL的表格中刪除一個或多個存儲過程。
***********************************************************************
變量做用域
內部變量在其做用域範圍內享有更高的優先權,當執行到end時,內部變量消失,再也不可見了,在存儲過程外再也找不到這個內部變量,可是能夠經過out參數或者將其值指派給回話變量來保存其值。
#變量做用域 DELIMITER // CREATE PROCEDURE proc() BEGIN DECLARE x1 VARCHAR(5) DEFAULT 'outer'; BEGIN DECLARE x1 VARCHAR(5) DEFAULT 'inner'; SELECT x1; END; SELECT x1; END; // DELIMITER ; #調用 CALL proc();
定義局部變量,那麼變量名加上‘@’。
set @var=(select cnm FROM tbnm); select @var=cnm FROM tbnm;
***************************************************************************
條件語句
#條件語句IF-THEN-ELSE DROP PROCEDURE IF EXISTS proc3; DELIMITER // CREATE PROCEDURE proc3(IN parameter int) BEGIN DECLARE var int; SET var=parameter+1; IF var=0 THEN INSERT INTO t VALUES (17); END IF ; IF parameter=0 THEN UPDATE t SET s1=s1+1; ELSE UPDATE t SET s1=s1+2; END IF ; END ; // DELIMITER ;
循環語句
while-do...end-while
DELIMITER // CREATE PROCEDURE proc5() BEGIN DECLARE var INT; SET var=0; WHILE var<6 DO INSERT INTO t VALUES (var); SET var=var+1; END WHILE ; END; // DELIMITER ;
repeat...end repeat
此語句的特色是執行操做後檢查結果 DELIMITER // CREATE PROCEDURE proc6 () BEGIN DECLARE v INT; SET v=0; REPEAT INSERT INTO t VALUES(v); SET v=v+1; UNTIL v>=5 END REPEAT; END; // DELIMITER ;
loop...end loop
DELIMITER // CREATE PROCEDURE proc7 () BEGIN DECLARE v INT; SET v=0; LOOP_LABLE:LOOP INSERT INTO t VALUES(v); SET v=v+1; IF v >=5 THEN LEAVE LOOP_LABLE; END IF; END LOOP; END; // DELIMITER ;
LABLES標號
標號能夠用在begin repeat while 或者loop 語句前,語句標號只能在合法的語句前面使用。能夠跳出循環,使運行指令達到複合語句的最後一步。
ITERATE迭代
ITERATE語句也是用來跳出循環的語句。可是,ITERATE語句是跳出本次循環,而後直接進入下一次循環。
ITERATE語句的基本語法形式以下:
ITERATE label
其中,label參數表示循環的標誌。
ITERATE語句只能夠出如今LOOP、REPEAT、WHILE語句內。
經過引用複合語句的標號,來重新開始複合語句 #ITERATE DELIMITER // CREATE PROCEDURE proc8() BEGIN DECLARE v INT; SET v=0; LOOP_LABLE:LOOP IF v=3 THEN SET v=v+1; ITERATE LOOP_LABLE; END IF; INSERT INTO t VALUES(v); SET v=v+1; IF v>=5 THEN LEAVE LOOP_LABLE; END IF; END LOOP; END; // DELIMITER ;
該示例循環執行count加1的操做,count值爲100時結束循環。若是count的值可以整除3,則跳出本次循環,再也不執行下面的SELECT語句。
說明:LEAVE語句和ITERATE語句都用來跳出循環語句,但二者的功能是不同的。
LEAVE語句是跳出整個循環,而後執行循環後面的程序。而ITERATE語句是跳出本次循環,而後進入下一次循環。
使用這兩個語句時必定要區分清楚。
************************************************************************
mysql存儲過程、自定義函數中使用的基本函數
charset(str)//返回字串字符集
concat(string1,string2)//返回字符串
instr(string,substring)//返回substring首次在string中出現的位置,不存在返回0
lcase(string)//轉化成小寫
ucase(string)//轉化成大寫
left(string,length)//從string的左邊取length個字符
right(string,length)//取string2最後length個字符
length(string)//string長度
load_file(file_name)//從文件讀取內容
locate(substring,string[,start_position])//同instr,但可指定開始位置
lpad(string,length,pad)//重複用pad加載string開頭,直到字符串長度爲length
ltrim(string)//除去前端空格
repeat(string,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
trim//去除指定位置的指定字符
SPACE(count) //生成count個空格