MySQL數(shù)據(jù)庫第八章-數(shù)據(jù)庫編程課件_第1頁
MySQL數(shù)據(jù)庫第八章-數(shù)據(jù)庫編程課件_第2頁
MySQL數(shù)據(jù)庫第八章-數(shù)據(jù)庫編程課件_第3頁
MySQL數(shù)據(jù)庫第八章-數(shù)據(jù)庫編程課件_第4頁
MySQL數(shù)據(jù)庫第八章-數(shù)據(jù)庫編程課件_第5頁
已閱讀5頁,還剩83頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第八章數(shù)據(jù)庫編程第八章數(shù)據(jù)庫編程項目知識要點與目標(biāo)項目知識要點與目標(biāo)任務(wù)一MySQL語言結(jié)構(gòu)1.字符串常量

字符串是指用單引號或雙引號括起來的字符序列,分為ASCII字符串常量和Unicode字符串常量。ASCII字符串常量是用單引號括起來的,由ASCII字符構(gòu)成的符號串。舉例:‘hello’,‘Howareyou!’Unicode字符串常量與ASCII字符串常量相似,但它前面有一個N標(biāo)志符(N代表SQL-92標(biāo)準(zhǔn)中的國際語言(NationalLanguage))。N前綴必須為大寫。只能用單引號括起字符串。舉例:N‘hello’,N‘Howareyou!’Unicode數(shù)據(jù)中的每個字符用兩個字節(jié)存儲,而每個ASCII字符用一個字節(jié)存儲。

在字符串中不僅可以使用普通的字符,也可使用幾個轉(zhuǎn)義序列,它們用來表示特殊的字符。SELECT'This\nIs\nFour\nLines';

其中,“\n”表示回車。任務(wù)一MySQL語言結(jié)構(gòu)1.字符串常量常量2.?dāng)?shù)值常量

數(shù)值常量可以分為整數(shù)常量和浮點數(shù)常量。3.十六進制常量

一個十六進制值通常指定為一個字符串常量,每對十六進制數(shù)字被轉(zhuǎn)換為一個字符,其最前面有一個大寫字母“X”或小寫字“x”。4.日期時間常量

日期時間常量:用單引號將表示日期時間的字符串括起來構(gòu)成。日期型常量包括年、月、日,數(shù)據(jù)類型為DATE,表示為“1999-06-17”這樣的值。

時間型常量包括小時數(shù)、分鐘數(shù)、秒數(shù)及微秒數(shù),數(shù)據(jù)類型為TIME,如“12:30:43.00013”。

日期/時間的組合,數(shù)據(jù)類型為DATETIME或TIMESTAMP,如“1999-06-1712:30:43”。常量2.?dāng)?shù)值常量常量5.位字段值

可以使用b'value'符號寫位字段值。value是一個用0和1寫成的二進制值。直接顯示b'value'的值可能是一系列特殊的符號。例如,b'0'顯示為空白,b'1'顯示為一個笑臉圖標(biāo)。

使用BIN函數(shù)可以將位字段常量顯示為二進制格式。6.布爾值

布爾值只包含兩個可能的值:TRUE和FALSE。FALSE的數(shù)字值為“0”,TRUE的數(shù)字值為“1”。7.NULL值NULL值可適用于各種列類型,它通常用來表示“沒有值”、“無數(shù)據(jù)”等意義,并且不同于數(shù)字類型的“0”或字符串類型的空字符串。常量5.位字段值用戶變量

變量用于臨時存放數(shù)據(jù),變量有名字及其數(shù)據(jù)類型兩個屬性,變量名用于標(biāo)識該變量,變量的數(shù)據(jù)類型確定了該變量存放值的格式及允許的運算。MySQL中根據(jù)變量的定義方式,變量可分為用戶變量和系統(tǒng)變量。1.用戶變量

用戶可以在表達式中使用自己定義的變量,這樣的變量叫做用戶變量。在使用用戶變量前必須定義和初始化。如果使用沒有初始化的變量,它的值為NULL。

定義和初始化一個變量可以使用SET語句

語法格式為:

SET@user_variable1=expression1[,user_variable2=expression2,…]

其中,user_variable1、user_variable2為用戶變量名,變量名可以由當(dāng)前字符集的文字數(shù)字字符、“.”、“_”和“$”組成。用戶變量變量用于臨時存放數(shù)據(jù),變量有名字及其數(shù)據(jù)類型變量舉例【例】創(chuàng)建用戶變量name并賦值為“王林”。

SET@name='王林';

還可以同時定義多個變量,中間用逗號隔開。【例】創(chuàng)建用戶變量user1并賦值為1,user2賦值為2,user3賦值為3。SET@user1=1,@user2=2,@user3=3;

定義用戶變量時變量值可以是一個表達式。【例】創(chuàng)建用戶變量user4,它的值為user3的值加1。SET@user4=@user3+1;在一個用戶變量被創(chuàng)建后,它可以以一種特殊形式的表達式用于其他SQL語句中。變量名前面也必須加上符號@。【例】創(chuàng)建并查詢用戶變量name的值。SET@name='王林';SELECT@name;變量舉例【例】創(chuàng)建用戶變量name并賦值為“王林”。變量舉例【例8.1】查詢Book表中圖書編號為TP302/057的書名,并存儲在變量b_name中。

SET

@b_name=(SELECT書名FROMBookWHERE圖書編號='TP302/057');

查詢Book表中名字等于例8.1中b_name值的圖書信息。

SELECT*FROMBookWHERE書名=@b_name;

變量舉例【例8.1】查詢Book表中圖書編號為TP302/0系統(tǒng)變量MySQL有一些特定的設(shè)置,當(dāng)MySQL數(shù)據(jù)庫服務(wù)器啟動的時候,這些設(shè)置被讀取來決定下一步驟。例如,有些設(shè)置定義了數(shù)據(jù)如何被存儲,有些設(shè)置則影響到處理速度,還有些與日期有關(guān),這些設(shè)置就是系統(tǒng)變量。和用戶變量一樣,系統(tǒng)變量也是一個值和一個數(shù)據(jù)類型,但不同的是,系統(tǒng)變量在MySQL服務(wù)器啟動時就被引入并初始化為默認值?!纠揩@得現(xiàn)在使用的MySQL版本。SELECT@@VERSION;說明:在MySQL中,系統(tǒng)變量VERSION的值設(shè)置為版本號。在變量名前必須加兩個@符號才能正確返回該變量的值。

大多數(shù)的系統(tǒng)變量應(yīng)用于其他SQL語句中時,必須在名稱前加兩個@符號,而為了與其他SQL產(chǎn)品保持一致,某些特定的系統(tǒng)變量是要省略這兩個@符號的。如CURRENT_DATE(系統(tǒng)日期)【例】獲得系統(tǒng)當(dāng)前時間。

SELECTCURRENT_TIME;系統(tǒng)變量MySQL有一些特定的設(shè)置,當(dāng)MySQL數(shù)據(jù)運算符1.算術(shù)運算符

算術(shù)運算符在兩個表達式上執(zhí)行數(shù)學(xué)運算,這兩個表達式可以是任何數(shù)字數(shù)據(jù)類型。算術(shù)運算符有:+(加)、(減)、*(乘)、/(除)和%(求模)5種運算。2.比較運算符

比較運算符(又稱關(guān)系運算符),用于比較兩個表達式的值,其運算結(jié)果為邏輯值,可以為三種之一:1(真)、0(假)及NULL(不能確定)。3、邏輯運算符

邏輯運算符用于對某個條件進行測試,運算結(jié)果為TRUE(1)或FALSE(0)。4、運算符優(yōu)先級

當(dāng)一個復(fù)雜的表達式有多個運算符時,運算符優(yōu)先級決定執(zhí)行運算的先后次序。執(zhí)行的順序會影響所得到的運算結(jié)果。運算符優(yōu)先級如下表所示。運算符1.算術(shù)運算符表達式

表達式就是常量、變量、列名、復(fù)雜計算、運算符和函數(shù)的組合。一個表達式通常可以得到一個值。與常量和變量一樣,表達式的值也具有某種數(shù)據(jù)類型,可能的數(shù)據(jù)類型有字符類型、數(shù)值類型、日期時間類型。這樣,根據(jù)表達式的值的類型,表達式可分為字符型表達式、數(shù)值型表達式和日期表達式。

表達式按照形式還可分為單一表達式和復(fù)合表達式。

單一表達式就是一個單一的值,如一個常量或列名。

復(fù)合表達式是由運算符將多個單一表達式連接而成的表達式例如:1+2+3,a=b+3,'2008-01-20'+INTERVAL2MONTH。表達式一般用在SELECT及SELECT語句的WHERE子句中。表達式表達式就是常量、變量、列名、復(fù)雜計算、運算符和函數(shù)流程控制語句在MySQL中,常見的過程式SQL語句可以用在一個存儲過程體中。例如:IF語句、CASE語句、LOOP語句、WHILE語句、ITERATE語句和LEAVE語句。(1)IF語句語法格式為:IF

search_conditionTHEN

statement_list[ELSEIF

search_conditionTHEN

statement_list]...[ELSE

statement_list]ENDIF流程控制語句在MySQL中,常見的過程式SQL語句可以用在一IF語句舉例DELIMITER$$CREATEPROCEDURECOMPAR(INK1INTEGER,INK2INTEGER,OUTK3CHAR(6))BEGIN IFK1>K2THEN SETK3='大于'; ELSEIFK1=K2THEN SETK3='等于'; ELSE SETK3='小于'; ENDIF;END$$DELIMITER;說明:存儲過程中K1和K2是輸入?yún)?shù),K3是輸出參數(shù)。要比較的數(shù)存入K1,K2“大于”=>K3K1>K2?K1=K2?“等于”=>K3“小于”=>K3輸出K3是否是否【例8.5】創(chuàng)建XSCJ數(shù)據(jù)庫的存儲過程,判斷兩個輸入的參數(shù)哪一個更大。IF語句舉例DELIMITER$$要比較的數(shù)存入K1,K2CASE語句(2)CASE語句語法格式為:CASEcase_value

WHENwhen_valueTHENstatement_list[WHENwhen_valueTHENstatement_list]...[ELSEstatement_list]ENDCASE或者:CASE

WHENsearch_conditionTHENstatement_list[WHENsearch_conditionTHENstatement_list]...[ELSEstatement_list]ENDCASE說明:一個CASE語句經(jīng)??梢猿洚?dāng)一個IF-THEN-ELSE語句。第一種格式中case_value是要被判斷的值或表達式,接下來是一系列的WHEN-THEN塊,每一塊的when_value參數(shù)指定要與case_value比較的值,如果為真,就執(zhí)行statement_list中的SQL語句。如果前面的每一個塊都不匹配就會執(zhí)行ELSE塊指定的語句。CASE語句最后以ENDCASE結(jié)束。第二種格式中CASE關(guān)鍵字后面沒有參數(shù),在WHEN-THEN塊中,search_condition指定了一個比較表達式,表達式為真時執(zhí)行THEN后面的語句。與第一種格式相比,這種格式能夠?qū)崿F(xiàn)更為復(fù)雜的條件判斷,使用起來更方便。CASE語句(2)CASE語句【例8.6】創(chuàng)建一個存儲過程,當(dāng)給定參數(shù)為U時返回“上升”,給定參數(shù)為D時返回“下降”,給定其他參數(shù)時返回“不變”。DELIMITER$$CREATEPROCEDUREvar_cp (INstrVARCHAR(1),OUTdirectVARCHAR(4))BEGINCASEstr WHEN'U'THENSETdirect='上升'; WHEN'D'THENSETdirect='下降'; ELSESETdirect='不變'; ENDCASE;END$$DELIMITER;以上的CASE語句用第二種格式來寫如下:CASE WHENstr='U'THENSETdirect='上升'; WHENstr='D'THENSETdirect='下降'; ELSESETdirect='不變';ENDCASE;CASE語句舉例【例8.6】創(chuàng)建一個存儲過程,當(dāng)給定參數(shù)為U時返回“上升”循環(huán)語句(3)循環(huán)語句MySQL支持3條用來創(chuàng)建循環(huán)的語句:WHILE、REPEAT和LOOP語句?!馱HILE語句語法格式為:[begin_label:]WHILEsearch_conditionDO statement_listENDWHILE[end_label]說明:語句首先判斷search_condition是否為真,不為真則執(zhí)行statement_list中的語句,然后再次進行判斷,為真則繼續(xù)循環(huán),不為真則結(jié)束循環(huán)。begin_label和end_label是WHILE語句的標(biāo)注。除非begin_label存在,否則end_label不能被給出,并且如果兩者都出現(xiàn),它們的名字必須是相同的。循環(huán)語句(3)循環(huán)語句WHILE語句舉例【例8.7】創(chuàng)建一個帶WHILE循環(huán)的存儲過程。DELIMITER$$CREATEPROCEDUREdowhile()BEGINDECLAREv1INTDEFAULT5;WHILEv1>0DOSETv1=v11;ENDWHILE;END$$DELIMITER;說明:當(dāng)調(diào)用這個存儲過程時,首先判斷v1的值是否大于零,如果大于零則執(zhí)行v11,否則結(jié)束循環(huán)。WHILE語句舉例【例8.7】創(chuàng)建一個帶WHILE循環(huán)的存REPEAT語句●REPEAT語句格式如下:[begin_label:]REPEATstatement_listUNTILsearch_conditionENDREPEAT[end_label]說明:REPEAT語句首先執(zhí)行statement_list中的語句,然后判斷search_condition是否為真,為真則停止循環(huán),不為真則繼續(xù)循環(huán)。REPEAT也可以被標(biāo)注?!纠坑肦EPEAT語句創(chuàng)建一個如例8.7的存儲過程。程序片段如下:REPEATv1=v11;UNTILv1<1;ENDREPEAT;說明:REPEAT語句和WHILE語句的區(qū)別在于:REPEAT語句先執(zhí)行語句,后進行判斷;而WHILE語句是先判斷,條件為真時才執(zhí)行語句。REPEAT語句●REPEAT語句格式如下:LOOP語句●LOOP語句語法格式如下:[begin_label:]LOOPstatement_listENDLOOP[end_label]說明:LOOP允許某特定語句或語句群的重復(fù)執(zhí)行,實現(xiàn)一個簡單的循環(huán)構(gòu)造,statement_list是需要重復(fù)執(zhí)行的語句。在循環(huán)內(nèi)的語句一直重復(fù)至循環(huán)被退出,退出時通常伴隨著一個LEAVE語句。結(jié)構(gòu)如下:LEAVElabel【例】用LOOP語句創(chuàng)建一個如例8.7的存儲過程。DELIMITER$$CREATEPROCEDUREdoloop()BEGINSETa=10;Label:LOOPSETa=a1;IFa<0THENLEAVELabel;ENDIF;ENDLOOPLabel;END$$DELIMITER;LOOP語句●LOOP語句語法格式如下:任務(wù)二存儲過程使用存儲過程的優(yōu)點有:(1)存儲過程在服務(wù)器端運行,執(zhí)行速度快。(2)存儲過程執(zhí)行一次后,其執(zhí)行規(guī)劃就駐留在高速緩沖存儲器,在以后的操作中,只需從高速緩沖存儲器中調(diào)用已編譯好的二進制代碼執(zhí)行,提高了系統(tǒng)性能。(3)確保數(shù)據(jù)庫的安全。使用存儲過程可以完成所有數(shù)據(jù)庫操作,并可通過編程方式控制上述操作對數(shù)據(jù)庫信息訪問的權(quán)限。任務(wù)二存儲過程創(chuàng)建存儲過程創(chuàng)建存儲過程可以使用CREATEPROCEDURE語句語法格式:CREATEPROCEDUREsp_name([proc_parameter[,...]])routine_body其中,proc_parameter的參數(shù)如下:[IN|OUT|INOUT]param_nametype說明:param_name為參數(shù)名,type為參數(shù)的類型,當(dāng)有多個參數(shù)的時候中間用逗號隔開。存儲過程可以有0個、1個或多個參數(shù)。MySQL存儲過程支持三種類型的參數(shù):輸入?yún)?shù)、輸出參數(shù)和輸入/輸出參數(shù),關(guān)鍵字分別是IN、OUT和INOUT。輸入?yún)?shù)使數(shù)據(jù)可以傳遞給一個存儲過程。當(dāng)需要返回一個答案或結(jié)果的時候,存儲過程使用輸出參數(shù)。輸入/輸出參數(shù)既可以充當(dāng)輸入?yún)?shù)也可以充當(dāng)輸出參數(shù)。存儲過程也可以不加參數(shù),但是名稱后面的括號是不可省略的。

routine_body:這是存儲過程的主體部分,也叫做存儲過程體。里面包含了在過程調(diào)用的時候必須執(zhí)行的語句,這個部分總是以BEGIN開始,以END結(jié)束。當(dāng)然,當(dāng)存儲過程體中只有一個SQL語句時可以省略BEGIN-END標(biāo)志。創(chuàng)建存儲過程創(chuàng)建存儲過程可以使用CREATEPROCEDUDELIMITER命令在MySQL中,服務(wù)器處理語句的時候是以分號為結(jié)束標(biāo)志的。但是在創(chuàng)建存儲過程的時候,存儲過程體中可能包含多個SQL語句,每個SQL語句都是以分號為結(jié)尾的,這時服務(wù)器處理程序的時候遇到第一個分號就會認為程序結(jié)束,這肯定是不行的。所以這里使用DELIMITER命令將MySQL語句的結(jié)束標(biāo)志修改為其他符號。DELIMITER語法格式為:

DELIMITER$$說明:$$是用戶定義的結(jié)束符,通常這個符號可以是一些特殊的符號,如兩個“#”,兩個“¥”等。當(dāng)使用DELIMITER命令時,應(yīng)該避免使用反斜杠(“\”)字符,因為那是MySQL的轉(zhuǎn)義字符?!纠繉ySQL結(jié)束符修改為兩個斜杠“/”符號。DELIMITER//說明:執(zhí)行完這條命令后,程序結(jié)束的標(biāo)志就換為雙斜杠符號“//”了。要想恢復(fù)使用分號“;”作為結(jié)束符,運行下面命令即可:DELIMITER;DELIMITER命令在MySQL中,服務(wù)器處理語句的時候是創(chuàng)建存儲過程舉例【例8.8】編寫一個存儲過程,實現(xiàn)的功能是刪除一個指定用戶姓名的用戶信息。DELIMITER$$CREATEPROCEDUREdel_member(INxmCHAR(8))BEGIN DELETEFROMMembersWHERE姓名=xm;END$$DELIMITER;

在關(guān)鍵字BEGIN和END之間指定了存儲過程體,因為在程序開始用DELIMITER語句轉(zhuǎn)換了語句結(jié)束標(biāo)志為“$$”,所以BEGIN和END被看成是一個整體,在END后用“$$”結(jié)束。當(dāng)然,BEGIN-END復(fù)合語句還可以嵌套使用。當(dāng)調(diào)用這個存儲過程時,MySQL根據(jù)提供的參數(shù)sfz的值,刪除對應(yīng)在members表中的數(shù)據(jù)。調(diào)用存儲過程的命令是CALL命令,后面會講到。

要想查看數(shù)據(jù)庫中有哪些存儲過程,可以使用SHOWPROCEDURESTATUS命令。SHOWPROCEDURESTATUS要查看某個存儲過程的具體信息,可使用SHOWCREATEPROCEDUREsp_name命令,其中sp_name是存儲過程的名稱。SHOWCREATEPROCEDUREDELETE_STUDENT創(chuàng)建存儲過程舉例【例8.8】編寫一個存儲過程,實現(xiàn)的功能是DECLARE語句1.局部變量在存儲過程中可以聲明局部變量,它們可以用來存儲臨時結(jié)果。要聲明局部變量必須使用DECLARE語句。在聲明局部變量的同時也可以對其賦一個初始值。語法格式:DECLAREvar_name[,...]type[DEFAULT

value]說明:var_name為變量名;type為變量類型;DEFAULT子句給變量指定一個默認值,如果不指定默認為NULL的話?!纠柯暶饕粋€整型變量和兩個字符變量。DECLAREnumINT(4);DECLAREstr1,str2VARCHAR(6);說明:局部變量只能在BEGIN…END語句塊中聲明。局部變量必須在存儲過程的開頭就聲明,聲明完后,可以在聲明它的BEGIN…END語句塊中使用該變量,其他語句塊中不可以使用它。DECLARE語句1.局部變量SET語句2.使用SET語句賦值要給局部變量賦值可以使用SET語句。語法格式為:SETvar_name=expr【例】在存儲過程中給局部變量賦值。

SETnum=1,str1='hello';SET語句2.使用SET語句賦值SELECT...INTO語句3.SELECT...INTO語句使用這個SELECT…INTO語法可以把選定的列值直接存儲到變量中。因此,返回的結(jié)果只能有一行。語法格式為:SELECTcol_name[,...]

INTO

var_name[,...]table_expr【例8.20】在存儲過程體中將Book表中的書名為“計算機基礎(chǔ)”的作者姓名和出版社的值分別賦給變量name和publish。

SELECT作者,出版社INTOname,publish FROMBook WHERE書名='計算機基礎(chǔ)';SELECT...INTO語句3.SELECT...IN調(diào)用存儲過程

存儲過程創(chuàng)建完后,可以在程序、觸發(fā)器或者存儲過程中被調(diào)用,調(diào)用時都必須使用到CALL語句,

其語法格式:CALLsp_name([parameter[,...]])說明:sp_name為存儲過程的名稱,如果要調(diào)用某個特定數(shù)據(jù)庫的存儲過程,則需要在前面加上該數(shù)據(jù)庫的名稱。parameter為調(diào)用該存儲過程使用的參數(shù),這條語句中的參數(shù)個數(shù)必須總是等于存儲過程的參數(shù)個數(shù)。

如調(diào)用【例8.8】的存儲過程,刪除“張三”的的用戶信息。

CALLdel_member('張三');調(diào)用存儲過程存儲過程創(chuàng)建完后,可以在程序、觸發(fā)器或者調(diào)用存儲過程【例8.10】創(chuàng)建存儲過程實現(xiàn)查詢Members表中會員人數(shù)的功能,并執(zhí)行它。首先創(chuàng)建查詢Members表中會員人數(shù)的存儲過程:

CREATEPROCEDUREquery_members() SELECTCOUNT(*)FROMMembers;這是一個不帶參數(shù)的非常簡單的存儲過程,通常SELECT語句不會被直接用在存儲過程中。調(diào)用該存儲過程:CALLquery_members();說明:通常SELECT語句不會被直接用在存儲過程中。調(diào)用存儲過程【例8.10】創(chuàng)建存儲過程實現(xiàn)查詢Member刪除存儲過程

存儲過程創(chuàng)建后需要刪除時使用DROPPROCEDURE語句。在此之前,必須確認該存儲過程沒有任何依賴關(guān)系,否則會導(dǎo)致其他與之關(guān)聯(lián)的存儲過程無法運行。

語法格式為:DROPPROCEDURE[IFEXISTS]sp_name說明:sp_name是要刪除的存儲過程的名稱。IFEXISTS子句是MySQL的擴展,如果程序或函數(shù)不存在,它防止發(fā)生錯誤?!纠縿h除存儲過程DO_QUERY()。

DROPPROCEDUREIFEXISTSDO_QUERY();刪除存儲過程存儲過程創(chuàng)建后需要刪除時使用DROPP存儲過程創(chuàng)建完后,可以在程序、觸發(fā)器或者存儲過程中被調(diào)用,但是都必須使用到CALL語句。語法格式:CALLsp_name([parameter[,...]])parameter為調(diào)用該存儲過程使用的參數(shù),這條語句中的參數(shù)個數(shù)必須總是等于存儲過程的參數(shù)個數(shù)。如果是輸出變量,前面加@調(diào)用該存儲過程:CALLCOMPAR(3,6,@K);SELECT@K;說明:3和6相當(dāng)于輸入?yún)?shù)K1和K2,用戶變量K相當(dāng)于輸出參數(shù)K3??梢钥吹?,由于3<6,輸出參數(shù)K的值就為“小于”。調(diào)用存儲過程舉例調(diào)用存儲過程舉例【例8.12】創(chuàng)建一個Bookstore數(shù)據(jù)庫的存儲過程,根據(jù)用戶姓名和書名查詢訂單,如果訂購冊數(shù)小于5本不打折,訂購冊數(shù)在5-10本之間,訂購單價打九折,訂購冊數(shù)大于10本,訂購單價打八折。調(diào)用存儲過程舉例DELIMITER$$CREATEPROCEDUREdj_update(INc_nameCHAR(8),INb_nameCHAR(20))BEGINDECLAREbhCHAR(20);DECLAREyhhCHAR(10);DECLAREslTINYINT;SELECT用戶號INTOyhhFROMMembersWHERE姓名=c_name;SELECT圖書編號INTObhFROMBookWHERE書名=b_name;SELECT訂購冊數(shù)INTOslFROMSellWHERE用戶號=yhhAND圖書編號=bh;IFsl>=5ANDsl<=10THENUPDATESellSET訂購單價=訂購單價*0.9WHERE用戶號=yhhAND圖書編號=bh;ELSEIFsl>10THENUPDATESellSET訂購單價=訂購單價*0.8WHERE用戶號=yhhAND圖書編號=bh;ENDIF;ENDIF;END$$DELIMITER;【例8.12】創(chuàng)建一個Bookstore數(shù)據(jù)庫的存儲過程,接下來調(diào)用存儲過程調(diào)整會員“張三”購買圖書“PHP_MySQL網(wǎng)站制作”的訂購單價并查詢調(diào)用前后的結(jié)果。調(diào)用前:SELECT姓名,書名,訂購單價,訂購冊數(shù)FROMSellJOINBookONSell.圖書編號=Book.圖書編號JOINMembersONSell.用戶號=Members.用戶號WHERE書名='PHP_MySQL網(wǎng)站制作'AND姓名='張三';調(diào)用存儲過程舉例調(diào)用存儲過程dj_update:CALLdj_update('張三','PHP_MySQL網(wǎng)站制作');調(diào)用后:SELECT姓名,書名,訂購單價,訂購冊數(shù)FROMSellJOINBookONSell.圖書編號=Book.圖書編號JOINMembersONSell.用戶號=Members.用戶號WHERE書名='PHP_MySQL網(wǎng)站制作'AND姓名='張三';接下來調(diào)用存儲過程調(diào)整會員“張三”購買圖書“PHP_MySQ存儲過程的嵌套【例8.13】創(chuàng)建一個存儲過程sell_insert(),作用是向Sell表中插入一行數(shù)據(jù)。創(chuàng)建另外一個存儲過程sell_update,在其中調(diào)用第一個存儲過程,如果給定參數(shù)為0,則修改由第一個存儲過程插入記錄的是否發(fā)貨字段為'已發(fā)貨',如果給定參數(shù)為1則刪除第一個存儲過程插入的記錄,并將操作結(jié)果輸出。第一個存儲過程:向Sell表中插入一行數(shù)據(jù)。CREATEPROCEDUREsell_insert()INSERTINTOSellVALUES('18','C013','TP40/02',4,30,'2017-03-05',NULL,NULL,NULL);第二個存儲過程:調(diào)用第一個存儲過,并輸出結(jié)果DELIMITER$$CREATEPROCEDUREsell_update(INXINT(1),OUTSTRCHAR(8))BEGINCALLsell_insert();CASEWHENx=0THENUPDATESellSET是否發(fā)貨='已發(fā)貨'WHERE訂單號='17';SETSTR='修改成功';WHENX=1THENDELETEFROMSellWHERE訂單號='17';SETSTR='刪除成功';ENDCASE;ENDDELIMITER;接下來調(diào)用存儲過程sell_update來查看結(jié)果:CALLsell_update(1,@str);SELECT@str;結(jié)果為:刪除成功CALLsell_update(0,@str);SELECT@str;結(jié)果為:修改成功存儲過程的嵌套【例8.13】創(chuàng)建一個存儲過程sell_in任務(wù)三存儲函數(shù)存儲函數(shù)也是過程式對象之一,與存儲過程很相似。它們都是由SQL和過程式語句組成的代碼片斷,并且可以從應(yīng)用程序和SQL中調(diào)用。然而,它們也有一些區(qū)別:(1)存儲函數(shù)不能擁有輸出參數(shù),因為存儲函數(shù)本身就是輸出參數(shù);(2)不能用CALL語句來調(diào)用存儲函數(shù);(3)存儲函數(shù)必須包含一條RETURN語句,而這條特殊的SQL語句不允許包含于存儲過程中。創(chuàng)建存儲函數(shù)使用CREATEFUNCTION語句。語法格式:CREATEFUNCTIONsp_name([func_parameter[,...]])RETURNStypevalueroutine_body說明:存儲函數(shù)的定義格式和存儲過程相差不大。sp_name是存儲函數(shù)的名稱。存儲函數(shù)不能擁有與存儲過程相同的名字。func_parameter是存儲函數(shù)的參數(shù),參數(shù)只有名稱和類型,不能指定IN、OUT和INOUT。RETURNStype子句聲明函數(shù)返回值的數(shù)據(jù)類型。routine_body是存儲函數(shù)的主體,也叫存儲函數(shù)體,所有在存儲過程中使用的SQL語句在存儲函數(shù)中也適用。但是存儲函數(shù)體中必須包含一個RETURNvalue語句,value為存儲函數(shù)的返回值。這是存儲過程體中沒有的。任務(wù)三存儲函數(shù)存儲函數(shù)也是過程式對象之一,與存儲過程很相似創(chuàng)建存儲函數(shù)【例8.14】創(chuàng)建一個存儲函數(shù),它返回Book表中圖書數(shù)目作為結(jié)果。

DELIMITER$$

CREATEFUNCTIONnum_book()

RETURNSINTEGERBEGIN RETURN(SELECTCOUNT(*)FROMBook);END$$DELIMITER;說明:RETURN子句中包含SELECT語句時,SELECT語句的返回結(jié)果只能是一行且只能有一列值。要查看數(shù)據(jù)庫中有哪些存儲函數(shù),可以使用SHOWFUNCTIONSTATUS命令。

SHOWFUNCTIONSTATUS調(diào)用存儲函數(shù)存儲函數(shù)創(chuàng)建完后,就如同系統(tǒng)提供的內(nèi)置函數(shù)(如VERSION()),所以調(diào)用存儲函數(shù)的方法也差不多,都是使用SELECT關(guān)鍵字。語法格式為:SELECTsp_name([func_parameter[,...]])調(diào)用【例8.14】存儲函數(shù):num_book()創(chuàng)建存儲函數(shù)【例8.14】創(chuàng)建一個存儲函數(shù),它返回Book存儲函數(shù)舉例【例8.15】創(chuàng)建一個存儲函數(shù),返回Book表中某本書的作者姓名。DELIMITER$$CREATEFUNCTIONauthor_book(b_nameCHAR(20))RETURNSCHAR(8)BEGIN RETURN(SELECT作者FROMBookWHERE書名=b_name);END$$DELIMITER;

調(diào)用此存儲函數(shù):SELECTauthor_book(‘計算機應(yīng)用基礎(chǔ)’);存儲函數(shù)舉例【例8.15】創(chuàng)建一個存儲函數(shù),返回Book表【例8.16】創(chuàng)建一個存儲函數(shù)來刪除Sell表中有但Book表中不存在的記錄。DELIMITER$$CREATEFUNCTIONdel_Sell1(b_bhCHAR(20)) RETURNSBOOLEANBEGIN DECLAREbhCHAR(20); SELECT圖書編號INTObhFROMBookWHERE圖書編號=b_bh; IFbhISNULLTHEN DELETEFROMSellWHERE圖書編號=b_bh; RETURNTRUE; ELSE RETURNFALSE; ENDIF;END$$DELIMITER;

此存儲函數(shù)給定圖書編號作為輸入?yún)?shù),先按給定的圖書編號到Book表查找看有無該圖書編號的書,如果沒有,返回FALSE,如果有,返回TRUE,同時還要到Sell表中刪除該圖書編號的書。SELECTdel_Sell('

TP40/02');存儲函數(shù)舉例【例8.16】創(chuàng)建一個存儲函數(shù)來刪除Sell表中有但Boo任務(wù)四觸發(fā)器創(chuàng)建觸發(fā)器語法格式:CREATETRIGGER觸發(fā)器名,觸發(fā)時間,觸發(fā)事件ON表名

FOREACHROW觸發(fā)器動作說明:●觸發(fā)時刻:有兩個選項:AFTER和BEFORE,以表示觸發(fā)器是在激活它的語句之前或之后觸發(fā)。如果想要在激活觸發(fā)器的語句執(zhí)行之后執(zhí)行幾個或更多的改變,通常使用AFTER選項;如果想要驗證新數(shù)據(jù)是否滿足使用的限制,則使用BEFORE選項?!裼|發(fā)事件:可以是下述值之一:INSERT:將新行插入表時激活觸發(fā)器。例如,通過INSERT語句。UPDATE:更改某一行時激活觸發(fā)器。例如,通過UPDATE語句。DELETE:從表中刪除某一行時激活觸發(fā)器。例如,通過DELETE語句。●表名,指在表上發(fā)生觸發(fā)事件才會激活觸發(fā)器。同一個表不能擁有兩個具有相同觸發(fā)時刻和事件的觸發(fā)器。例如,對于某一表,不能有兩個BEFOREUPDATE觸發(fā)器,但可以有1個BEFOREUPDATE觸發(fā)器和1個BEFOREINSERT觸發(fā)器,或1個BEFOREUPDATE觸發(fā)器和1個AFTERUPDATE觸發(fā)器?!馞OREACHROW:表示對于受觸發(fā)事件影響的每一行,都要激活觸發(fā)器的動作。任務(wù)四觸發(fā)器創(chuàng)建觸發(fā)器語法格式:

創(chuàng)建觸發(fā)器舉例在MySQL觸發(fā)器中的SQL語句可以關(guān)聯(lián)表中的任意列。但不能直接使用列的名稱去標(biāo)志,那會使系統(tǒng)混淆,因為激活觸發(fā)器的語句可能已經(jīng)修改、刪除或添加了新的列名,而列的舊名同時存在。因此必須用這樣的語法來標(biāo)志:“NEW.column_name”或者“OLD.column_name”。NEW.column_name用來引用新行的一列,OLD.column_name用來引用更新或刪除它之前的已有行的一列。對于INSERT語句,只有NEW是合法的;對于DELETE語句,只有OLD才合法;而UPDATE語句可以與NEW或OLD同時使用。創(chuàng)建觸發(fā)器舉例在MySQL觸發(fā)器中的SQL語句可以關(guān)聯(lián)表中創(chuàng)建觸發(fā)器舉例【例8.19】創(chuàng)建一個觸發(fā)器,當(dāng)刪除表Book表中某圖書的信息時,同時將Sell表中與該圖書有關(guān)的數(shù)據(jù)全部刪除。DELIMITER$$CREATETRIGGERbook_delAFTERDELETE ONBookFOREACHROWBEGIN DELETEFROMSellWHERE圖書編號=OLD.圖書編號;END$$DELIMITER;

現(xiàn)在驗證一下觸發(fā)器的功能:DELETEFROMBookWHERE圖書編號='TP40/04';使用SELECT語句查看Sell表中的情況:SELECT*FROMSellWHERE圖書編號='TP40/04';這時可以發(fā)現(xiàn),圖書編號為'TP40/04'在Sell表中的所有信息已經(jīng)被刪除了。創(chuàng)建觸發(fā)器舉例【例8.19】創(chuàng)建一個觸發(fā)器,當(dāng)刪除表Boo創(chuàng)建觸發(fā)器舉例【例8.20】創(chuàng)建一個觸發(fā)器,當(dāng)修改Sell表中訂購冊數(shù)時,如果修改后的訂購冊數(shù)小于5本,則觸發(fā)器將該對應(yīng)的折扣修改為1,否則,折扣修改為0.8。

DELIMITER$$CREATETRIGGERsell_updateBEFOREUPDATE ONSellFOREACHROWBEGIN IFNEW.訂購冊數(shù)<5THEN UPDATEBookSET折扣=1WHERE圖書編號=NEW.圖書編號;ELSE UPDATEBookSET折扣=0.8WHERE圖書編號=NEW.圖書編號; ENDIF;END$$DELIMITER;因為是修改了Sell表的記錄后才執(zhí)行觸發(fā)器程序修改Book表中的記錄,此時Sell表中該記錄已經(jīng)修改了,所以只能用NEW.圖書編號來表示這個修改后的記錄的圖書編號,Book表使用WHERE圖書編號=NEW.圖書編號條件查找要修改的記錄。創(chuàng)建觸發(fā)器舉例【例8.20】創(chuàng)建一個觸發(fā)器,當(dāng)修改Sell創(chuàng)建觸發(fā)器舉例現(xiàn)在驗證觸發(fā)器的功能:UPDATESellSET訂購冊數(shù)=4WHERE圖書編號='TP10/04'AND用戶號='C0132';使用SELECT語句查看Book表中的情況:SELECT圖書編號,折扣FROMBookWHERE圖書編號='TP10/04';可以發(fā)現(xiàn),訂購冊數(shù)<5,折扣為1驗證觸發(fā)器的功能:UPDATESellSET訂購冊數(shù)=40WHERE圖書編號='TP10/04'AND用戶號='C0132';使用SELECT語句查看Book表中的情況:SELECT圖書編號,折扣FROMBookWHERE圖書編號='TP10/04';可以發(fā)現(xiàn),訂購冊數(shù)>5,折扣為0.8創(chuàng)建觸發(fā)器舉例【例8.21】創(chuàng)建觸發(fā)器,實現(xiàn)當(dāng)向Sell表插入一行數(shù)據(jù)時,根據(jù)訂購冊數(shù)對Book進行修改。如果訂購冊數(shù)>10,Book表中折扣在原折扣基礎(chǔ)上再打0.95折,否則折扣不變。DELIMITER$$CREATETRIGGERSell_insAFTERINSERT ONSellFOREACHROWBEGIN IFNEW.訂購冊數(shù)>10THEN UPDATEBookSET折扣=折扣*.95WHERE圖書編號=NEW.圖書編號; ENDIF;END$$DELIMITER;現(xiàn)在驗證一下觸發(fā)器的功能:先查詢沒插入記錄之前圖書編號為TP32/01的折扣:SELECT圖書編號,書名,折扣FROMBookWHERE圖書編號='TP32/01';向Sell表插入一行記錄:INSERTINTOSellVALUES('18','B0022','TP32/01',42,30,'2017-03-05',NULL,NULL,NULL);使用SELECT語句查看Book表中的情況:SELECT圖書編號,書名,折扣FROMBookWHERE圖書編號='TP32/01';創(chuàng)建觸發(fā)器舉例【例8.21】創(chuàng)建觸發(fā)器,實現(xiàn)當(dāng)向Sell表插入一行數(shù)據(jù)時觸發(fā)器的刪除和其他數(shù)據(jù)庫對象一樣,使用DROP語句即可將觸發(fā)器從數(shù)據(jù)庫中刪除。語法格式:DROPTRIGGERtrigger_name如刪除觸發(fā)器members_ins。

DROPTRIGGERmembers_ins;

創(chuàng)建觸發(fā)器使用CREATETRIGGER語句 ,要查看數(shù)據(jù)庫中有哪些觸發(fā)器可以使用SHOWTRIGGERS命令。

SHOWTRIGGERS觸發(fā)器的刪除和其他數(shù)據(jù)庫對象一樣,使用DROP語句即可將觸發(fā)第八章數(shù)據(jù)庫編程第八章數(shù)據(jù)庫編程項目知識要點與目標(biāo)項目知識要點與目標(biāo)任務(wù)一MySQL語言結(jié)構(gòu)1.字符串常量

字符串是指用單引號或雙引號括起來的字符序列,分為ASCII字符串常量和Unicode字符串常量。ASCII字符串常量是用單引號括起來的,由ASCII字符構(gòu)成的符號串。舉例:‘hello’,‘Howareyou!’Unicode字符串常量與ASCII字符串常量相似,但它前面有一個N標(biāo)志符(N代表SQL-92標(biāo)準(zhǔn)中的國際語言(NationalLanguage))。N前綴必須為大寫。只能用單引號括起字符串。舉例:N‘hello’,N‘Howareyou!’Unicode數(shù)據(jù)中的每個字符用兩個字節(jié)存儲,而每個ASCII字符用一個字節(jié)存儲。

在字符串中不僅可以使用普通的字符,也可使用幾個轉(zhuǎn)義序列,它們用來表示特殊的字符。SELECT'This\nIs\nFour\nLines';

其中,“\n”表示回車。任務(wù)一MySQL語言結(jié)構(gòu)1.字符串常量常量2.?dāng)?shù)值常量

數(shù)值常量可以分為整數(shù)常量和浮點數(shù)常量。3.十六進制常量

一個十六進制值通常指定為一個字符串常量,每對十六進制數(shù)字被轉(zhuǎn)換為一個字符,其最前面有一個大寫字母“X”或小寫字“x”。4.日期時間常量

日期時間常量:用單引號將表示日期時間的字符串括起來構(gòu)成。日期型常量包括年、月、日,數(shù)據(jù)類型為DATE,表示為“1999-06-17”這樣的值。

時間型常量包括小時數(shù)、分鐘數(shù)、秒數(shù)及微秒數(shù),數(shù)據(jù)類型為TIME,如“12:30:43.00013”。

日期/時間的組合,數(shù)據(jù)類型為DATETIME或TIMESTAMP,如“1999-06-1712:30:43”。常量2.?dāng)?shù)值常量常量5.位字段值

可以使用b'value'符號寫位字段值。value是一個用0和1寫成的二進制值。直接顯示b'value'的值可能是一系列特殊的符號。例如,b'0'顯示為空白,b'1'顯示為一個笑臉圖標(biāo)。

使用BIN函數(shù)可以將位字段常量顯示為二進制格式。6.布爾值

布爾值只包含兩個可能的值:TRUE和FALSE。FALSE的數(shù)字值為“0”,TRUE的數(shù)字值為“1”。7.NULL值NULL值可適用于各種列類型,它通常用來表示“沒有值”、“無數(shù)據(jù)”等意義,并且不同于數(shù)字類型的“0”或字符串類型的空字符串。常量5.位字段值用戶變量

變量用于臨時存放數(shù)據(jù),變量有名字及其數(shù)據(jù)類型兩個屬性,變量名用于標(biāo)識該變量,變量的數(shù)據(jù)類型確定了該變量存放值的格式及允許的運算。MySQL中根據(jù)變量的定義方式,變量可分為用戶變量和系統(tǒng)變量。1.用戶變量

用戶可以在表達式中使用自己定義的變量,這樣的變量叫做用戶變量。在使用用戶變量前必須定義和初始化。如果使用沒有初始化的變量,它的值為NULL。

定義和初始化一個變量可以使用SET語句

語法格式為:

SET@user_variable1=expression1[,user_variable2=expression2,…]

其中,user_variable1、user_variable2為用戶變量名,變量名可以由當(dāng)前字符集的文字數(shù)字字符、“.”、“_”和“$”組成。用戶變量變量用于臨時存放數(shù)據(jù),變量有名字及其數(shù)據(jù)類型變量舉例【例】創(chuàng)建用戶變量name并賦值為“王林”。

SET@name='王林';

還可以同時定義多個變量,中間用逗號隔開?!纠縿?chuàng)建用戶變量user1并賦值為1,user2賦值為2,user3賦值為3。SET@user1=1,@user2=2,@user3=3;

定義用戶變量時變量值可以是一個表達式?!纠縿?chuàng)建用戶變量user4,它的值為user3的值加1。SET@user4=@user3+1;在一個用戶變量被創(chuàng)建后,它可以以一種特殊形式的表達式用于其他SQL語句中。變量名前面也必須加上符號@?!纠縿?chuàng)建并查詢用戶變量name的值。SET@name='王林';SELECT@name;變量舉例【例】創(chuàng)建用戶變量name并賦值為“王林”。變量舉例【例8.1】查詢Book表中圖書編號為TP302/057的書名,并存儲在變量b_name中。

SET

@b_name=(SELECT書名FROMBookWHERE圖書編號='TP302/057');

查詢Book表中名字等于例8.1中b_name值的圖書信息。

SELECT*FROMBookWHERE書名=@b_name;

變量舉例【例8.1】查詢Book表中圖書編號為TP302/0系統(tǒng)變量MySQL有一些特定的設(shè)置,當(dāng)MySQL數(shù)據(jù)庫服務(wù)器啟動的時候,這些設(shè)置被讀取來決定下一步驟。例如,有些設(shè)置定義了數(shù)據(jù)如何被存儲,有些設(shè)置則影響到處理速度,還有些與日期有關(guān),這些設(shè)置就是系統(tǒng)變量。和用戶變量一樣,系統(tǒng)變量也是一個值和一個數(shù)據(jù)類型,但不同的是,系統(tǒng)變量在MySQL服務(wù)器啟動時就被引入并初始化為默認值。【例】獲得現(xiàn)在使用的MySQL版本。SELECT@@VERSION;說明:在MySQL中,系統(tǒng)變量VERSION的值設(shè)置為版本號。在變量名前必須加兩個@符號才能正確返回該變量的值。

大多數(shù)的系統(tǒng)變量應(yīng)用于其他SQL語句中時,必須在名稱前加兩個@符號,而為了與其他SQL產(chǎn)品保持一致,某些特定的系統(tǒng)變量是要省略這兩個@符號的。如CURRENT_DATE(系統(tǒng)日期)【例】獲得系統(tǒng)當(dāng)前時間。

SELECTCURRENT_TIME;系統(tǒng)變量MySQL有一些特定的設(shè)置,當(dāng)MySQL數(shù)據(jù)運算符1.算術(shù)運算符

算術(shù)運算符在兩個表達式上執(zhí)行數(shù)學(xué)運算,這兩個表達式可以是任何數(shù)字數(shù)據(jù)類型。算術(shù)運算符有:+(加)、(減)、*(乘)、/(除)和%(求模)5種運算。2.比較運算符

比較運算符(又稱關(guān)系運算符),用于比較兩個表達式的值,其運算結(jié)果為邏輯值,可以為三種之一:1(真)、0(假)及NULL(不能確定)。3、邏輯運算符

邏輯運算符用于對某個條件進行測試,運算結(jié)果為TRUE(1)或FALSE(0)。4、運算符優(yōu)先級

當(dāng)一個復(fù)雜的表達式有多個運算符時,運算符優(yōu)先級決定執(zhí)行運算的先后次序。執(zhí)行的順序會影響所得到的運算結(jié)果。運算符優(yōu)先級如下表所示。運算符1.算術(shù)運算符表達式

表達式就是常量、變量、列名、復(fù)雜計算、運算符和函數(shù)的組合。一個表達式通??梢缘玫揭粋€值。與常量和變量一樣,表達式的值也具有某種數(shù)據(jù)類型,可能的數(shù)據(jù)類型有字符類型、數(shù)值類型、日期時間類型。這樣,根據(jù)表達式的值的類型,表達式可分為字符型表達式、數(shù)值型表達式和日期表達式。

表達式按照形式還可分為單一表達式和復(fù)合表達式。

單一表達式就是一個單一的值,如一個常量或列名。

復(fù)合表達式是由運算符將多個單一表達式連接而成的表達式例如:1+2+3,a=b+3,'2008-01-20'+INTERVAL2MONTH。表達式一般用在SELECT及SELECT語句的WHERE子句中。表達式表達式就是常量、變量、列名、復(fù)雜計算、運算符和函數(shù)流程控制語句在MySQL中,常見的過程式SQL語句可以用在一個存儲過程體中。例如:IF語句、CASE語句、LOOP語句、WHILE語句、ITERATE語句和LEAVE語句。(1)IF語句語法格式為:IF

search_conditionTHEN

statement_list[ELSEIF

search_conditionTHEN

statement_list]...[ELSE

statement_list]ENDIF流程控制語句在MySQL中,常見的過程式SQL語句可以用在一IF語句舉例DELIMITER$$CREATEPROCEDURECOMPAR(INK1INTEGER,INK2INTEGER,OUTK3CHAR(6))BEGIN IFK1>K2THEN SETK3='大于'; ELSEIFK1=K2THEN SETK3='等于'; ELSE SETK3='小于'; ENDIF;END$$DELIMITER;說明:存儲過程中K1和K2是輸入?yún)?shù),K3是輸出參數(shù)。要比較的數(shù)存入K1,K2“大于”=>K3K1>K2?K1=K2?“等于”=>K3“小于”=>K3輸出K3是否是否【例8.5】創(chuàng)建XSCJ數(shù)據(jù)庫的存儲過程,判斷兩個輸入的參數(shù)哪一個更大。IF語句舉例DELIMITER$$要比較的數(shù)存入K1,K2CASE語句(2)CASE語句語法格式為:CASEcase_value

WHENwhen_valueTHENstatement_list[WHENwhen_valueTHENstatement_list]...[ELSEstatement_list]ENDCASE或者:CASE

WHENsearch_conditionTHENstatement_list[WHENsearch_conditionTHENstatement_list]...[ELSEstatement_list]ENDCASE說明:一個CASE語句經(jīng)??梢猿洚?dāng)一個IF-THEN-ELSE語句。第一種格式中case_value是要被判斷的值或表達式,接下來是一系列的WHEN-THEN塊,每一塊的when_value參數(shù)指定要與case_value比較的值,如果為真,就執(zhí)行statement_list中的SQL語句。如果前面的每一個塊都不匹配就會執(zhí)行ELSE塊指定的語句。CASE語句最后以ENDCASE結(jié)束。第二種格式中CASE關(guān)鍵字后面沒有參數(shù),在WHEN-THEN塊中,search_condition指定了一個比較表達式,表達式為真時執(zhí)行THEN后面的語句。與第一種格式相比,這種格式能夠?qū)崿F(xiàn)更為復(fù)雜的條件判斷,使用起來更方便。CASE語句(2)CASE語句【例8.6】創(chuàng)建一個存儲過程,當(dāng)給定參數(shù)為U時返回“上升”,給定參數(shù)為D時返回“下降”,給定其他參數(shù)時返回“不變”。DELIMITER$$CREATEPROCEDUREvar_cp (INstrVARCHAR(1),OUTdirectVARCHAR(4))BEGINCASEstr WHEN'U'THENSETdirect='上升'; WHEN'D'THENSETdirect='下降'; ELSESETdirect='不變'; ENDCASE;END$$DELIMITER;以上的CASE語句用第二種格式來寫如下:CASE WHENstr='U'THENSETdirect='上升'; WHENstr='D'THENSETdirect='下降'; ELSESETdirect='不變';ENDCASE;CASE語句舉例【例8.6】創(chuàng)建一個存儲過程,當(dāng)給定參數(shù)為U時返回“上升”循環(huán)語句(3)循環(huán)語句MySQL支持3條用來創(chuàng)建循環(huán)的語句:WHILE、REPEAT和LOOP語句?!馱HILE語句語法格式為:[begin_label:]WHILEsearch_conditionDO statement_listENDWHILE[end_label]說明:語句首先判斷search_condition是否為真,不為真則執(zhí)行statement_list中的語句,然后再次進行判斷,為真則繼續(xù)循環(huán),不為真則結(jié)束循環(huán)。begin_label和end_label是WHILE語句的標(biāo)注。除非begin_label存在,否則end_label不能被給出,并且如果兩者都出現(xiàn),它們的名字必須是相同的。循環(huán)語句(3)循環(huán)語句WHILE語句舉例【例8.7】創(chuàng)建一個帶WHILE循環(huán)的存儲過程。DELIMITER$$CREATEPROCEDUREdowhile()BEGINDECLAREv1INTDEFAULT5;WHILEv1>0DOSETv1=v11;ENDWHILE;END$$DELIMITER;說明:當(dāng)調(diào)用這個存儲過程時,首先判斷v1的值是否大于零,如果大于零則執(zhí)行v11,否則結(jié)束循環(huán)。WHILE語句舉例【例8.7】創(chuàng)建一個帶WHILE循環(huán)的存REPEAT語句●REPEAT語句格式如下:[begin_label:]REPEATstatement_listUNTILsearch_conditionENDREPEAT[end_label]說明:REPEAT語句首先執(zhí)行statement_list中的語句,然后判斷search_condition是否為真,為真則停止循環(huán),不為真則繼續(xù)循環(huán)。REPEAT也可以被標(biāo)注?!纠坑肦EPEAT語句創(chuàng)建一個如例8.7的存儲過程。程序片段如下:REPEATv1=v11;UNTILv1<1;ENDREPEAT;說明:REPEAT語句和WHILE語句的區(qū)別在于:REPEAT語句先執(zhí)行語句,后進行判斷;而WHILE語句是先判斷,條件為真時才執(zhí)行語句。REPEAT語句●REPEAT語句格式如下:LOOP語句●LOOP語句語法格式如下:[begin_label:]LOOPstatement_listENDLOOP[end_label]說明:LOOP允許某特定語句或語句群的重復(fù)執(zhí)行,實現(xiàn)一個簡單的循環(huán)構(gòu)造,statement_list是需要重復(fù)執(zhí)行的語句。在循環(huán)內(nèi)的語句一直重復(fù)至循環(huán)被退出,退出時通常伴隨著一個LEAVE語句。結(jié)構(gòu)如下:LEAVElabel【例】用LOOP語句創(chuàng)建一個如例8.7的存儲過程。DELIMITER$$CREATEPROCEDUREdoloop()BEGINSETa=10;Label:LOOPSETa=a1;IFa<0THENLEAVELabel;ENDIF;ENDLOOPLabel;END$$DELIMITER;LOOP語句●LOOP語句語法格式如下:任務(wù)二存儲過程使用存儲過程的優(yōu)點有:(1)存儲過程在服務(wù)器端運行,執(zhí)行速度快。(2)存儲過程執(zhí)行一次后,其執(zhí)行規(guī)劃就駐留在高速緩沖存儲器,在以后的操作中,只需從高速緩沖存儲器中調(diào)用已編譯好的二進制代碼執(zhí)行,提高了系統(tǒng)性能。(3)確保數(shù)據(jù)庫的安全。使用存儲過程可以完成所有數(shù)據(jù)庫操作,并可通過編程方式控制上述操作對數(shù)據(jù)庫信息訪問的權(quán)限。任務(wù)二存儲過程創(chuàng)建存儲過程創(chuàng)建存儲過程可以使用CREATEPROCEDURE語句語法格式:CREATEPROCEDUREsp_name([proc_parameter[,...]])routine_body其中,proc_parameter的參數(shù)如下:[IN|OUT|INOUT]param_nametype說明:param_name為參數(shù)名,type為參數(shù)的類型,當(dāng)有多個參數(shù)的時候中間用逗號隔開。存儲過程可以有0個、1個或多個參數(shù)。MySQL存儲過程支持三種類型的參數(shù):輸入?yún)?shù)、輸出參數(shù)和輸入/輸出參數(shù),關(guān)鍵字分別是IN、OUT和INOUT。輸入?yún)?shù)使數(shù)據(jù)可以傳遞給一個存儲過程。當(dāng)需要返回一個答案或結(jié)果的時候,存儲過程使用輸出參數(shù)。輸入/輸出參數(shù)既可以充當(dāng)輸入?yún)?shù)也可以充當(dāng)輸出參數(shù)。存儲過程也可以不加參數(shù),但是名稱后面的括號是不可省略的。

routine_body:這是存儲過程的主體部分,也叫做存儲過程體。里面包含了在過程調(diào)用的時候必須執(zhí)行的語句,這個部分總是以BEGIN開始,以END結(jié)束。當(dāng)然,當(dāng)存儲過程體中只有一個SQL語句時可以省略BEGIN-END標(biāo)志。創(chuàng)建存儲過程創(chuàng)建存儲過程可以使用CREATEPROCEDUDELIMITER命令在MySQL中,服務(wù)器處理語句的時候是以分號為結(jié)束標(biāo)志的。但是在創(chuàng)建存儲過程的時候,存儲過程體中可能包含多個SQL語句,每個SQL語句都是以分號為結(jié)尾的,這時服務(wù)器處理程序的時候遇到第一個分號就會認為程序結(jié)束,這肯定是不行的。所以這里使用DELIMITER命令將MySQL語句的結(jié)束標(biāo)志修改為其他符號。DELIMITER語法格式為:

DELIMITER$$說明:$$是用戶定義的結(jié)束符,通常這個符號可以是一些特殊的符號,如兩個“#”,兩個“¥”等。當(dāng)使用DELIMITER命令時,應(yīng)該避免使用反斜杠(“\”)字符,因為那是MySQL的轉(zhuǎn)義字符?!纠繉ySQL結(jié)束符修改為兩個斜杠“/”符號。DELIMITER//說明:執(zhí)行完這條命令后,程序結(jié)束的標(biāo)志就換為雙斜杠符號“//”了。要想恢復(fù)使用分號“;”作為結(jié)束符,運行下面命令即可:DELIMITER;DELIMITER命令在MySQL中,服務(wù)器處理語句的時候是創(chuàng)建存儲過程舉例【例8.8】編寫一個存儲過程,實現(xiàn)的功能是刪除一個指定用戶姓名的用戶信息。DELIMITER$$CREATEPROCEDUREdel_member(INxmCHAR(8))BEGIN DELETEFROMMembersWHERE姓名=xm;END$$DELIMITER;

在關(guān)鍵字BEGIN和END之間指定了存儲過程體,因為在程序開始用DELIMITER語句轉(zhuǎn)換了語句結(jié)束標(biāo)志為“$$”,所以BEGIN和END被看成是一個整體,在END后用“$$”結(jié)束。當(dāng)然,BEGIN-END復(fù)合語句還可以嵌套使用。當(dāng)調(diào)用這個存儲過程時,MySQL根據(jù)提供的參數(shù)sfz的值,刪除對應(yīng)在members表中的數(shù)據(jù)。調(diào)用存儲過程的命令是CALL命令,后面會講到。

要想查看數(shù)據(jù)庫中有哪些存儲過程,可以使用SHOWPROCEDURESTATUS命令。SHOWPROCEDURESTATUS要查看某個存儲過程的具體信息,可使用SHOWCREATEPROCEDUREsp_name命令,其中sp_name是存儲過程的名稱。SHOWCREATEPROCEDUREDELETE_STUDENT創(chuàng)建存儲過程舉例【例8.8】編寫一個存儲過程,實現(xiàn)的功能是DECLARE語句1.局部變量在存儲過程中可以聲明局部變量,它們可以用來存儲臨時結(jié)果。要聲明局部變量必須使用DECLARE語句。在聲明局部變量的同時也可以對其賦一個初始值。語法格式:DECLAREvar_name[,...]type[DEFAULT

value]說明:var_name為變量名;type為變量類型;DEFAULT子句給變量指定一個默認值,如果不指定默認為NULL的話?!纠柯暶饕粋€整型變量和兩個字符變量。DECLAREnumINT(4);DE

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論