存儲過程
存儲過程(Stored Procedure)是在大型數(shù)據(jù)庫系統(tǒng)中蛮寂,一組為了完成特定功能的SQL 語句集雏掠,存儲在數(shù)據(jù)庫中下愈,經(jīng)過第一次編譯后再次調(diào)用不需要再次編譯矫钓,用戶通過指定存儲過程的名字并給出參數(shù)(如果該存儲過程帶有參數(shù))來執(zhí)行它。存儲過程是數(shù)據(jù)庫中的一個重要對象铁瞒。
語法:
CREATE? PROCEDURE? 過程名 ([[IN|OUT|INOUT] 參數(shù)名 數(shù)據(jù)類型
? ? ? ? ? ? ? ? ? ? ? [,[IN|OUT|INOUT] 參數(shù)名 數(shù)據(jù)類型…]])
? BEGIN
? ? ? 過程體
? END;
舉例:
DELIMITER //
CREATE PROCEDURE myproc(OUT s int)? ?
?BEGIN? ? ? ??
SELECT COUNT(*) INTO s FROM students;
? ? END;
//DELIMITER ;
說明:
分隔符
? ? ? MySQL默認以";"為分隔符妙色,如果沒有聲明分割符,則編譯器會把存儲過程當成SQL語句進行處理慧耍,因此編譯過程會報錯身辨,所以要事先用“DELIMITER //”聲明當前段分隔符,讓編譯器把兩個"http://"之間的內(nèi)容當做存儲過程的代碼蜂绎,不會執(zhí)行這些代碼栅表;“DELIMITER ;”的意為把分隔符還原笋鄙。
參數(shù)
? ? ? 存儲過程根據(jù)需要可能會有輸入师枣、輸出、輸入輸出參數(shù)萧落,如果有多個參數(shù)用","分割開践美。MySQL存儲過程的參數(shù)用在存儲過程的定義洗贰,共有三種參數(shù)類型,IN,OUT,INOUT:
? ? ? IN參數(shù)的值必須在調(diào)用存儲過程時指定,在存儲過程中修改該參數(shù)的值不能被返回陨倡,為默認值 OUT:該值可在存儲過程內(nèi)部被改變敛滋,并可返回 INOUT:調(diào)用時指定,并且可被改變和返回兴革。
過程體
? ? ? 過程體的開始與結(jié)束使用BEGIN與END進行標識绎晃。
存儲過程是一組SQL語句
增強SQL語言的功能和靈活性:
? ? ? ? 存儲過程可以用控制語句編寫,有很強的靈活性杂曲,可以完成復(fù)雜的判斷和較復(fù)雜的運算庶艾。
提升復(fù)用程度 :
? ? ? ? 存儲過程被創(chuàng)建后,可以在程序中被多次調(diào)用擎勘,而不必重新編寫該存儲過程的SQL語句咱揍。
較快的執(zhí)行速度:
? ? ? ? 存儲過程是預(yù)編譯的。而批處理的SQL語句在每次運行時都要進行編譯和優(yōu)化棚饵,速度相對要慢一些煤裙。
減少網(wǎng)絡(luò)流量:
? ? ? 針對同一個數(shù)據(jù)庫對象的操作,如果操作的SQL語句寫在存儲過程,當在客戶計算機上調(diào)用該存儲過程時噪漾,網(wǎng)絡(luò)中傳送的只是該調(diào)用語句硼砰,從而大大減少網(wǎng)絡(luò)流量并降低了網(wǎng)絡(luò)負載
調(diào)用存儲過程
語法:
? ? ? ? CALL? precedure_name([param1,param2]…..)
舉例:
? ? ? ? CALL? pr_add(10, 20);
用戶定義變量?
MySQL存儲過程中,定義變量有兩種方式:
用戶變量:
? ? ? 使用SET或SELECT直接賦值欣硼,變量名以 @ 開頭.
例如: SET @var=1;
? ? ? ? SELECT @var:=5;
? ? ? ? SELECT? empno,ename INTO @var,@name FROM EMP WHERE empno =7499 ;
可以在一個會話的任何地方聲明夺刑,用戶變量可以作用于當前整個連接,但是當前連接斷開后分别,其所定義的用戶變量都會消失稱為用戶變量遍愿。
局部變量:
? ? DECLARE 關(guān)鍵字聲明的變量,只能在存儲過程中使用耘斩,稱為存儲過程變量沼填,
? 格式:
DECLARE? varname1[,varname2] ……? datatype? [DEFAULT VALUE]
? 例如:
DECLARE var1 INT DEFAULT 0;
DECLAR? v1,v2? VARCHAR(20);
SET C= 5; //賦值
SELECT? empno,empname INTO var1,v1? FROM emp WHERE empno =7499;
局部變量一般用在sql語句塊中,比如存儲過程的begin/end括授。其作用域僅限于該語句塊坞笙,在該語句塊執(zhí)行完畢后,局部變量就消失了荚虚。
條件結(jié)構(gòu)
If語句
①語法結(jié)構(gòu):
if? ? 條件表達式1? then
語句塊1;
end if;
說明:end if后必須以“;”結(jié)束
舉例:
????????DELIMITER //
????????CREATE PROCEDURE pTest()
? ? ? ? BEGIN
? ? ????????? DECLARE vHour INT;
? ? ????????? SET vHour =10;
? ? ????????? IF vHour>40 THEN
? ? ? ? ????????? SELECT '加班了';
? ? ? ????????END IF;
????????END//
????????DELIMITER?
②語法結(jié)構(gòu):
if? ? 條件表達式1? then
? ? ? 語句塊;
else?
語句塊薛夜;
end if;
說明:end if后必須以“;”結(jié)束
舉例:
????????DELIMITER //
????????CREATE PROCEDURE pTest()
? ???????? BEGIN
? ? ????????? DECLARE vHour INT;
? ? ? ????????SET vHour =10;
? ? ????????? IF vHour>40 THEN
? ? ? ? ? ????????SELECT '加班了';
? ????????? ? ELSE
? ? ? ? ? ????????SELECT '沒加班';
????????? ? ? END IF;
????????END//
????????DELIMITER?
③語法結(jié)構(gòu):
if? ? 條件表達式1? then
? ? ? 語句塊1;
[elseif 條件表達式2? then
? ? ? 語句塊2] ...
[else? 語句塊n]
end if;
說明:end if后必須以“;”結(jié)束
舉例:
????????DELIMITER $$
????????CREATE PROCEDURE pTest()
????????BEGIN
????????? ? ? DECLARE vHour INT;
? ? ????????? SET vHour =60;
? ? ????????? IF vHour>70 THEN
? ? ????????? ? ? SELECT '加班超多';
????????? ? ? ELSEIF vHour> 50 AND vHour<=70? THEN
? ????????? ? ? ? SELECT '加班多';
????????? ? ? ELSEIF vHour >40 AND vHour<=50 THEN
? ? ? ? ????????? SELECT '有加班';
? ? ????????? ELSE
? ????????? ? ? ? SELECT '沒加班';
????????? ? ? END IF;
????????END$$
????????DELIMITER ;
case語句
①語法結(jié)構(gòu):
case 表達式
? when value1 then? 語句塊1;
? when value2 then? 語句塊2;
? ? …
? else 語句塊n;
end case;
舉例:
????????DELIMITER //
????????CREATE PROCEDURE pCase()
????????? BEGIN
????????? ? ? DECLARE? job CHAR(50);
????????? ? ? SET job ='a';
????????? ? ? CASE job
????????? ? ? WHEN 'a' THEN SELECT '工作是經(jīng)理';
? ????????? ? WHEN 'b' THEN SELECT '工作是財務(wù)';
????????? ? ? WHEN 'c' THEN SELECT '工作是人事';
? ????????? ? WHEN 'd' THEN SELECT '工作是行政';
? ????????? ? ELSE SELECT '是其它工作';
? ????????? ? END CASE;
????????END;//
????????DELIMITER?
②語法結(jié)構(gòu):
case 表達式
? when value1 then? 語句塊1;
? when value2 then? 語句塊2;
? ? …
? else 語句塊n;
end case;
舉例:
????????DELIMITER //
????????CREATE PROCEDURE pCase()
????????? BEGIN
? ????????? ? DECLARE? job CHAR(50);
? ? ????????? SET job ='a';
? ? ????????? CASE job
? ????????? ? WHEN 'a' THEN SELECT '工作是經(jīng)理';
????????? ? ? WHEN 'b' THEN SELECT '工作是財務(wù)';
????????? ? ? WHEN 'c' THEN SELECT '工作是人事';
????????? ? ? WHEN 'd' THEN SELECT '工作是行政';
? ????????? ? ELSE SELECT '是其它工作';
????????? ? ? END CASE;
????????END;//
????????DELIMITER ;
③語法結(jié)構(gòu):
case
? when 表達式1? then? 語句塊1;
? when 表達式2? then? 語句塊2;
? ? …
? else 語句塊n;
end case;
舉例:
????????DELIMITER //
????????CREATE PROCEDURE pCase2()
????????? BEGIN
????????? ? ? DECLARE vNum CHAR(20);
????????? ? ? SET vNum = 80;
????????? ? ? CASE
????????WHEN vNum IS NULL THEN SELECT '沒有分數(shù)';
????????WHEN vNum>90 THEN SELECT '成績優(yōu)異';
????????WHEN vNum<90 AND vNum>=60 THEN SELECT '成績良';
????????ELSE SELECT '沒有及格';
????????? ? ? END CASE;
????????END;//
????????DELIMITER ;
循環(huán)結(jié)構(gòu)
MySQL提供了三種循環(huán)語句:
????While
????Loop
????Repeat
除此以外,MySQL還提供了iterate語句以及l(fā)eave語句用于循環(huán)的控制版述。
while語句結(jié)構(gòu):
while? ? 條件表達式? ? do
? ? ? 循環(huán)體;
end while ;
說明:
1)end while后必須以“;”結(jié)束
2)當條件表達式的值為true時,反復(fù)執(zhí)行循環(huán)體
? ? ,直到條件表達式的值為false
語法結(jié)構(gòu):
????????DELIMITER //
????????CREATE? PROCEDURE pWhile()
????????BEGIN
???????? ? ? DECLARE vNum INT;
????????? ? ? SET vNum = 0;
????????? ? ? WHILE vNum<20 DO
????????SET vNum= vNum + 1;
????????? ? ? END WHILE;
????????? ? SELECT vNum;
????????END;//
????????DELIMITER ;
Loop循環(huán)格式:
[循環(huán)標簽:] loop
? 循環(huán)體;
? if 條件表達式 then?
? ? ? leave [循環(huán)標簽];
? end if;
end loop;
說明:end loop后必須以“;”結(jié)束
????????DELIMITER //
????????CREATE? PROCEDURE pLoop()
????????BEGIN
????????? ? ? DECLARE vNum INT;
? ????????? ? SET vNum = 0;
????????? ? ? addLoop:LOOP
????????IF vNum>20 THEN
????????? LEAVE addLoop;
????????END IF;
????????SET vNum= vNum + 1;
????????? ? ? END LOOP addloop;
????????? ? SELECT vNum;
????????END;//
????????DELIMITER ;
Leave關(guān)鍵字:用于跳出當前的循環(huán)語句(例如while語句)
? 語法格式如下:
? ? ? leave 循環(huán)標簽;
? 說明:leave 循環(huán)標簽后必須以“;”結(jié)束
Iterate關(guān)鍵字:用于跳出本次循環(huán)梯澜,繼而進行下次循環(huán)。
? 語法格式:
? ? ? ? Iterate 循環(huán)標簽;
? ? 說明:iterate循環(huán)標簽后必須以“;”結(jié)束
Iterate語句:
????????DELIMITER //
????????CREATE? PROCEDURE piterate()
????????BEGIN
? ????????? ? DECLARE vNum INT;
????????? ? ? SET vNum = 0;
????????? ? ? addLoop:LOOP
????????? ? ? ? SET vNum= vNum + 1;
????????? ? ? ? IF vNum<10 THEN ITERATE addloop;
? ????????? ? ? ELSEIF vNum>20 THEN LEAVE addloop;
????????END IF;
????????SELECT 'vnum <=0 and vnum >=10';
? ????????? ? END LOOP addloop;
????????? ? SELECT vNum;
????????END;//
????????DELIMITER ;
repeat語句:
? 當條件表達式的值為false時渴析,反復(fù)執(zhí)行循環(huán)晚伙,
? ? 直到條件表達式的值為true
[循環(huán)標簽:]repeat
? ? 循環(huán)體;
? ? until 條件表達式
end repeat [循環(huán)標簽];
說明:end repeat后必須以“;”結(jié)束
????????DELIMITER //
????????CREATE? PROCEDURE prepeat()
????????BEGIN
????????? ? ? DECLARE vNum INT;
????????? ? ? SET vNum = 0;
????????? ? ? addrepeat:REPEAT
? ????????? ? ? SET vNum= vNum + 1;
????????UNTIL vNum>20
????????? ? ? END REPEAT addrepeat;
????????? ? SELECT vNum;
????????END;//
????????DELIMITER ;