SQL存儲過程

存儲過程

存儲過程(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 ;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吮龄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子咆疗,更是在濱河造成了極大的恐慌漓帚,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件午磁,死亡現(xiàn)場離奇詭異尝抖,居然都是意外死亡,警方通過查閱死者的電腦和手機迅皇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門牵署,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喧半,你說我怎么就攤上這事却妨∫嬗” “怎么了捻撑?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵其掂,是天一觀的道長。 經(jīng)常有香客問我扁耐,道長暇检,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任婉称,我火速辦了婚禮块仆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘王暗。我一直安慰自己悔据,他們只是感情好,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布俗壹。 她就那樣靜靜地躺著科汗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绷雏。 梳的紋絲不亂的頭發(fā)上头滔,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音涎显,去河邊找鬼坤检。 笑死,一個胖子當著我的面吹牛期吓,可吹牛的內(nèi)容都是我干的早歇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缺前!你這毒婦竟也來了蛀醉?” 一聲冷哼從身側(cè)響起悬襟,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤衅码,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后脊岳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逝段,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年割捅,在試婚紗的時候發(fā)現(xiàn)自己被綠了奶躯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡亿驾,死狀恐怖嘹黔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情莫瞬,我是刑警寧澤儡蔓,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站疼邀,受9級特大地震影響喂江,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜旁振,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一获询、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拐袜,春花似錦吉嚣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至丛塌,卻和暖如春较解,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赴邻。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工印衔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姥敛。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓奸焙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子与帆,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容