Oracle數(shù)據(jù)庫(kù)教程 第7章課件_第1頁
Oracle數(shù)據(jù)庫(kù)教程 第7章課件_第2頁
Oracle數(shù)據(jù)庫(kù)教程 第7章課件_第3頁
Oracle數(shù)據(jù)庫(kù)教程 第7章課件_第4頁
Oracle數(shù)據(jù)庫(kù)教程 第7章課件_第5頁
已閱讀5頁,還剩79頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第7章PL/SQL編程第7章PL/SQL編程PL/SQL編程7.1PL/SQL語言基礎(chǔ)7.2PL/SQL程序結(jié)構(gòu)7.3異常處理PL/SQL編程7.1PL/SQL語言基礎(chǔ)7.1PL/SQL語言基礎(chǔ)7.1.1PL/SQL語言優(yōu)點(diǎn)PL/SQL是一種高效的事務(wù)處理語言,它具備以下優(yōu)點(diǎn):PL/SQL是一種高性能的基于事務(wù)處理的語言,能運(yùn)行在任何Oracle環(huán)境中,支持所有數(shù)據(jù)處理命令。通過使用PL/SQL程序單元處理SQL的數(shù)據(jù)定義和數(shù)據(jù)控制元素。PL/SQL支持所有SQL數(shù)據(jù)類型和所有SQL函數(shù),同時(shí)支持所有Oracle對(duì)象類型。PL/SQL塊可以被命名并存儲(chǔ)在Oracle服務(wù)器中,同時(shí)也能被其他PL/SQL程序或SQL命令調(diào)用,任何客戶/服務(wù)器工具都能訪問PL/SQL程序,具有很好的可重用性。可以使用Oracle數(shù)據(jù)工具管理PL/SQL程序的安全性??梢允跈?quán)或撤銷數(shù)據(jù)庫(kù)其他用戶訪問PL/SQL程序權(quán)限。7.1PL/SQL語言基礎(chǔ)7.1.1PL/SQL語言7.1PL/SQL語言基礎(chǔ)PL/SQL代碼可以使用任何ASCII文本編輯器編寫,所以對(duì)任何能夠運(yùn)行Oracle的操作系統(tǒng)都是非常便利的。對(duì)于SQL,Oracle必須在同一時(shí)間處理每一條SQL語句,在網(wǎng)絡(luò)環(huán)境下這就意味著每一個(gè)獨(dú)立的調(diào)用都必須被Oracle服務(wù)器處理,從而占用大量的服務(wù)器時(shí)間,導(dǎo)致網(wǎng)絡(luò)擁擠。而PL/SQL以整個(gè)語句塊形式發(fā)給服務(wù)器,可以減少網(wǎng)絡(luò)擁擠。7.1PL/SQL語言基礎(chǔ)PL/SQL代碼可以使用任何7.1PL/SQL語言基礎(chǔ)7.1.2PL/SQL的基本結(jié)構(gòu)一個(gè)PL/SQL程序包含一個(gè)或多個(gè)邏輯塊,每個(gè)塊都可以劃分為三個(gè)部分:聲明部分(用DECLARE開頭)、執(zhí)行部分(以BEGIN開頭)和異常處理部分(以EXCEPTION開頭)

1、PL/SQL基本結(jié)構(gòu)如下:

DECLARE

聲明部分

BEGIN

執(zhí)行部分

EXCEPTION

異常處理部分

END;7.1PL/SQL語言基礎(chǔ)7.1.2PL/SQL的基7.1PL/SQL語言基礎(chǔ)其中:聲明部分:定義變量和常量的數(shù)據(jù)類型和初始值,以及程序中要使用的函數(shù)、游標(biāo)、異常處理名稱等。如果沒有需要聲明的內(nèi)容,可以省略這一部分。PL/SQL中要使用的所有定義都必須在這一部分進(jìn)行集中定義。執(zhí)行部分:此部分是PL/SQL塊中的指令部分,所有的可執(zhí)行語句都放在這一部分,包括對(duì)數(shù)據(jù)庫(kù)的操作語句和各種流程控制語句,也可以嵌套其他的PL/SQL塊。執(zhí)行部分至少包含一條可執(zhí)行語句。異常處理部分:包含在執(zhí)行部分中,以關(guān)鍵字EXCEPTION開始,到END結(jié)束。當(dāng)程序檢測(cè)到錯(cuò)誤而產(chǎn)生異常時(shí),就轉(zhuǎn)到由EXCEPTION標(biāo)識(shí)的部分執(zhí)行異常處理程序。這部分是可選的,利用異常處理可以提高PL/SQL程序的健壯性。7.1PL/SQL語言基礎(chǔ)其中:7.1PL/SQL語言基礎(chǔ)2、

PL/SQL的特殊結(jié)構(gòu)

<<BLOCK1>>/*以名字標(biāo)識(shí)PL/SQL塊*/DECLARE

聲明部分BEGIN

執(zhí)行部分EXCEPTION

異常處理部分END<<BLOCK1>>;DECLARE

主塊聲明部分BEGIN

主塊執(zhí)行部分

DECLARE

子塊聲明部分

BEGIN

子塊執(zhí)行部分

EXCEPTION

子塊異常處理部分

END;EXCEPTION

主塊異常處理部分END;帶命名塊的PL/SQL塊嵌套結(jié)構(gòu)的PL/SQL塊7.1PL/SQL語言基礎(chǔ)2、PL/SQL的特殊結(jié)構(gòu)7.1PL/SQL語言基礎(chǔ)7.1.3PL/SQL的字符集1、合法字符,包括:大寫字母A-Z和小寫字母a-z數(shù)字0-9符號(hào)()、+、-、*、/、<、>、=、!、~、^、;、:、.、’、@、”、#、$、_、{}、[]、?制表符、空格符、回車符等非顯示的間空符號(hào)2、操作符,包括:算術(shù)操作符關(guān)系操作符邏輯操作符3、其他字符7.1PL/SQL語言基礎(chǔ)7.1.3PL/SQL的字7.1PL/SQL語言基礎(chǔ)7.1.4PL/SQL基本語法1、常量與變量的聲明,語法格式如下:

<常(變)量名>[CONSTANT]<數(shù)據(jù)類型>[NOTNULL][(寬度):=<初始值>]

【例7.1】幾個(gè)聲明的例子①聲明一個(gè)長(zhǎng)度為10B的變量count,初值為1,類型為VARCHAR2。

cvarchar2(10):='1';②聲明一個(gè)NUMBER數(shù)據(jù)類型的常量c_limit,并賦予初值5000.00。

c_limitconstantnumber(8.2):=5000.00;③聲明一個(gè)NUMBER數(shù)據(jù)類型的常量c_area,并用表達(dá)式給它賦初值。

c_areaconstantnumber(8.5):=3.14159*3**2;7.1PL/SQL語言基礎(chǔ)7.1.4PL/SQL基本7.1PL/SQL語言基礎(chǔ)2、作用域變量的作用域指變量的有效使用范圍,它從變量聲明開始,直到當(dāng)前程序塊結(jié)束,只有在其作用域范圍內(nèi),程序才能使用該變量,否則將導(dǎo)致編譯錯(cuò)誤。在同一程序塊中,不允許聲明兩個(gè)同名變量,但在不同程序塊內(nèi)可以聲明兩個(gè)同名變量。在程序塊內(nèi)聲明的變量稱為局部變量,在程序塊外聲明的變量稱為全局變量。引用程序塊內(nèi)的局部變量不需要加限定詞,而引用塊外的全局變量需要加限定詞(即父塊的名稱)。子塊中可以引用父塊的變量,但是父塊中不能引用子塊的變量。如果父塊與子塊具有相同的變量名,在子塊中引用這個(gè)變量時(shí)若是不加限定詞則引用的是子塊內(nèi)的局部變量。若兩個(gè)塊不是父子關(guān)系,則他們之間的變量不能相互引用。7.1PL/SQL語言基礎(chǔ)2、作用域7.1PL/SQL語言基礎(chǔ)(3)變量的屬性變量有名字和數(shù)據(jù)類型兩個(gè)屬性。變量名用于標(biāo)識(shí)該變量,變量的數(shù)據(jù)類型確定了該變量存放值的格式及允許的運(yùn)算。在PL/SQL中,使用“%”表示屬性提示符,后面緊跟屬性名。%TYPE和%ROWTYPE是PL/SQL中兩個(gè)特殊的屬性,常用來定義變量,使被定義變量的數(shù)據(jù)類型與一個(gè)已定義變量(或參照表中的記錄)的數(shù)據(jù)類型相一致。%TYPE使用%TYPE屬性定義變量時(shí),被定義變量的數(shù)據(jù)類型與一個(gè)已經(jīng)定義了的變量的數(shù)據(jù)類型相一致,當(dāng)被參照的變量數(shù)據(jù)類型改變后,新定義變量的數(shù)據(jù)類型也隨之改變。當(dāng)無法準(zhǔn)確知道被參照變量的數(shù)據(jù)類型時(shí),只能采用這種定義方法。定義格式為:<新變量名><被參照表.被參照列>%TYPE7.1PL/SQL語言基礎(chǔ)(3)變量的屬性7.1PL/SQL語言基礎(chǔ)【例7.1】聲明三個(gè)變量“v_班級(jí)名稱”,“v_班級(jí)人數(shù)”,“v_班主任”,其數(shù)據(jù)類型分別對(duì)應(yīng)“班級(jí)表”中相應(yīng)字段的數(shù)據(jù)類型。根據(jù)輸入的班級(jí)代碼,輸出對(duì)應(yīng)的班級(jí)名稱、人數(shù)和班主任信息。代碼如下:DECLAREv_班級(jí)名稱班級(jí)表.班級(jí)名稱%TYPE;v_班級(jí)人數(shù)班級(jí)表.班級(jí)人數(shù)%TYPE;v_班主任班級(jí)表.班主任%TYPE;BEGINSELECT班級(jí)名稱,班級(jí)人數(shù),班主任intov_班級(jí)名稱,v_班級(jí)人數(shù),v_班主任FROM班級(jí)表WHERE班級(jí)代碼='&班級(jí)代碼';DBMS_OUTPUT.PUT_LINE('班級(jí)名稱:'||v_班級(jí)名稱);DBMS_OUTPUT.PUT_LINE('班級(jí)人數(shù):'||v_班級(jí)人數(shù));DBMS_OUTPUT.PUT_LINE('班主任:'||v_班主任);END;語句:Setserverouton7.1PL/SQL語言基礎(chǔ)【例7.1】聲明三個(gè)變量“v7.1PL/SQL語言基礎(chǔ)%ROWTYPE使用%ROWTYPE屬性能夠定義記錄變量,使得被定義的記錄成員個(gè)數(shù)、名稱、數(shù)據(jù)類型與已定義的表或視圖中列的個(gè)數(shù)、名稱和數(shù)據(jù)類型完全相同。這種定義方式,可以定義一個(gè)表,當(dāng)被參照表中列及數(shù)據(jù)類型改變時(shí),新定義表中的列及數(shù)據(jù)類型自動(dòng)改變。當(dāng)一個(gè)表有較多列時(shí),使用%ROWTYPE定義記錄,比使用%TYPE要方便,并且不容易出錯(cuò)。定義格式為:<新表名><被參照表>%ROWTYPE7.1PL/SQL語言基礎(chǔ)%ROWTYPE7.1PL/SQL語言基礎(chǔ)【例7.2】聲明一個(gè)變量“v_班級(jí)”,與班級(jí)表具有相同的數(shù)據(jù)類型。根據(jù)輸入的班級(jí)代碼,輸出對(duì)應(yīng)的班級(jí)名稱、人數(shù)和班主任信息。代碼如下:DECLAREv_班級(jí)班級(jí)表%ROWTYPE;BEGINSELECT*intov_班級(jí)

FROM班級(jí)表WHERE班級(jí)代碼='&班級(jí)代碼';DBMS_OUTPUT.PUT_LINE('班級(jí)名稱:'||v_班級(jí).班級(jí)名稱);DBMS_OUTPUT.PUT_LINE('班級(jí)人數(shù):'||v_班級(jí).班級(jí)人數(shù));DBMS_OUTPUT.PUT_LINE('班主任:'||v_班級(jí).班主任);END;7.1PL/SQL語言基礎(chǔ)【例7.2】聲明一個(gè)變量“v7.1PL/SQL語言基礎(chǔ)3、數(shù)據(jù)類型標(biāo)量類型LOB型數(shù)據(jù)類型定義的運(yùn)算符7.1PL/SQL語言基礎(chǔ)3、數(shù)據(jù)類型7.1PL/SQL語言基礎(chǔ)【例7.3】聲明一個(gè)TIMESTAMP類型的變量,并為它賦值。代碼如下:SETSERVEROUTONDECLAREcheckoutTIMESTAMP(2);BEGINcheckout:='10-6月-07075';DBMS_OUTPUT.PUT_LINE(checkout);END;7.1PL/SQL語言基礎(chǔ)【例7.3】聲明一個(gè)TIME7.2PL/SQL程序結(jié)構(gòu)7.2.1選擇結(jié)構(gòu)選擇結(jié)構(gòu)又稱條件控制,通過先測(cè)試一個(gè)條件,根據(jù)測(cè)試結(jié)果選擇運(yùn)行不同的語句段。選擇結(jié)構(gòu)允許嵌套執(zhí)行。選擇結(jié)構(gòu)常用到的4種語法格式:IF…THEN…ENDIF結(jié)構(gòu)IF…THEN…ELSE…ENDIF結(jié)構(gòu)IF…THEN…ELSIF…ENDIF結(jié)構(gòu)CASE結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)7.2.1選擇結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)【例7.4】查找“ASP.NET程序設(shè)計(jì)”課程,若是“備注”信息為“C#”,將其改為“J#”,否則將“備注”信息置空。7.2PL/SQL程序結(jié)構(gòu)【例7.4】查找“ASP.N7.2PL/SQL程序結(jié)構(gòu)

DECLARE

v_課程課程表%ROWTYPE;

BEGIN

SELECT*INTOv_課程FROM課程表

WHERE課程名='ASP.NET程序設(shè)計(jì)';

IFv_課程.備注='C#'THEN

UPDATE課程表

SET備注='J#'

WHERE課程名=v_課程.課程名;

ELSE

UPDATE課程表

SET備注=''

WHERE課程名=v_課程.課程名;

ENDIF;

DBMS_OUTPUT.PUT_LINE('更新完成!');

END;

試一試:數(shù)據(jù)被修改了嗎?為什么?作業(yè)一、用你熟悉的方法完成該問題,比較兩種方法。7.2PL/SQL程序結(jié)構(gòu)DECLARE7.2PL/SQL程序結(jié)構(gòu)【例7.5】學(xué)生成績(jī)按照分?jǐn)?shù)段分為“優(yōu)秀”、“良好”、“合格”、“不及格”4種等級(jí),根據(jù)等級(jí)的不同,可以輸出對(duì)應(yīng)的分?jǐn)?shù)段,代碼如下:DECLAREv_resultVARCHAR2(20):='良好';BEGINIFv_result='優(yōu)秀'THENDBMS_OUTPUT.PUT_LINE('90~100');ELSIFv_result='良好'THENDBMS_OUTPUT.PUT_LINE('80~89');ELSIFv_result='合格'THENDBMS_OUTPUT.PUT_LINE('60~79');ELSIFv_result='不及格'THENDBMS_OUTPUT.PUT_LINE('<60');ELSEDBMS_OUTPUT.PUT_LINE('不存在該等級(jí)');ENDIF;END;7.2PL/SQL程序結(jié)構(gòu)【例7.5】學(xué)生成績(jī)按照分?jǐn)?shù)7.2PL/SQL程序結(jié)構(gòu)【例7.6】從“成績(jī)表”中根據(jù)學(xué)生的學(xué)號(hào)和課程號(hào)查找學(xué)生某門課程的成績(jī),并輸出成績(jī)的等級(jí)。采用CASE語法格式:7.2PL/SQL程序結(jié)構(gòu)【例7.6】從“成績(jī)表”中根7.2PL/SQL程序結(jié)構(gòu)DECLAREv_scoreNUMBER(3);BEGINSELECT成績(jī)intov_scoreFROM成績(jī)表WHERE學(xué)號(hào)=&學(xué)號(hào)and課程號(hào)=&課程號(hào);CASEWHEN(v_score>=90andv_score<=100)THENDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'優(yōu)秀');WHEN(v_score>=80andv_score<90)THENDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'良好');WHEN(v_score>=60andv_score<80)THENDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'合格');WHEN(v_score>=0andv_score<60)THENDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'不及格');ELSEDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'成績(jī)異常');ENDCASE;END;7.2PL/SQL程序結(jié)構(gòu)DECLARE7.2PL/SQL程序結(jié)構(gòu)【例7.7】使用CASE語句完成例7.5程序。要求使用CASE語句第二種語法格式實(shí)現(xiàn),代碼如下:DECLAREv_resultVARCHAR2(20):='良好';BEGINCASEv_resultWHEN'優(yōu)秀'THENDBMS_OUTPUT.PUT_LINE('90~100');WHEN'良好'THENDBMS_OUTPUT.PUT_LINE('80~89');WHEN'合格'THENDBMS_OUTPUT.PUT_LINE('60~79');WHEN'不及格'THENDBMS_OUTPUT.PUT_LINE('<60');ELSEDBMS_OUTPUT.PUT_LINE('不存在該等級(jí)');ENDCASE;END;7.2PL/SQL程序結(jié)構(gòu)【例7.7】使用CASE語句7.2PL/SQL程序結(jié)構(gòu)7.2.2循環(huán)結(jié)構(gòu)循環(huán)結(jié)構(gòu)可以對(duì)一段語句反復(fù)執(zhí)行,直到滿足某一條件,跳出循環(huán)

。循環(huán)結(jié)構(gòu)常用到的3種語法格式:LOOP…ENDLOOP結(jié)構(gòu)WHILE…LOOP…ENDLOOP結(jié)構(gòu)FOR…LOOP…ENDLOOP結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)7.2.2循環(huán)結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)【例7.8】利用LOOP循環(huán)和EXIT語句計(jì)算1至100的自然數(shù)之和。代碼如下:DECLAREv_iNUMBER:=1;v_sNUMBER:=0;BEGINLOOPEXITWHENv_i>100;v_s:=v_s+v_i;v_i:=v_i+1;ENDLOOP;DBMS_OUTPUT.PUT_LINE('1~100自然數(shù)之和:'||v_s);END;7.2PL/SQL程序結(jié)構(gòu)【例7.8】利用LOOP循環(huán)7.2PL/SQL程序結(jié)構(gòu)【例7.9】利用WHILE循環(huán)計(jì)算1至100的自然數(shù)之和。代碼如下:DECLAREv_iNUMBER:=0;v_sNUMBER:=0;BEGINWHILEv_i<=100LOOPv_s:=v_s+v_i;v_i:=v_i+1;ENDLOOP;DBMS_OUTPUT.PUT_LINE('1~100自然數(shù)之和:'||v_s);END;7.2PL/SQL程序結(jié)構(gòu)【例7.9】利用WHILE循7.2PL/SQL程序結(jié)構(gòu)【例7.10】利用FOR循環(huán)語句計(jì)算1至100的自然數(shù)之和。代碼如下:DECLAREv_sNUMBER:=0;BEGINFORv_iIN1..100LOOPv_s:=v_s+v_i;ENDLOOP;DBMS_OUTPUT.PUT_LINE('1~100自然數(shù)之和:'||v_s);END;思考題:如何利用循環(huán)語句生成數(shù)據(jù)?7.2PL/SQL程序結(jié)構(gòu)【例7.10】利用FOR循環(huán)7.2PL/SQL程序結(jié)構(gòu)7.2.3順序結(jié)構(gòu)順序結(jié)構(gòu)是一種最簡(jiǎn)單的控制結(jié)構(gòu),程序按語句順序依次執(zhí)行。有時(shí)為了打破執(zhí)行順序,將當(dāng)前程序跳轉(zhuǎn)到另一個(gè)地方繼續(xù)運(yùn)行,需要借助GOTO語句。GOTO語句是一種無條件跳轉(zhuǎn)語句,能夠?qū)⒄Z句無條件地跳轉(zhuǎn)到一個(gè)用標(biāo)簽指定的語句,其目的地必須與GOTO語句在同一程序塊中或更高層次(比如父塊中)中。但過多的使用GOTO語句會(huì)導(dǎo)致程序復(fù)雜,破壞程序的結(jié)構(gòu)。因此,GOTO語句一般只用在從一個(gè)PL/SQL塊中跳轉(zhuǎn)到異常處理語句的前面7.2PL/SQL程序結(jié)構(gòu)7.2.3順序結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)【例7.11】利用GOTO語句計(jì)算1至100的自然數(shù)之和。代碼如下:DECLAREv_iNUMBER:=0;v_sNUMBER:=0;BEGIN<<label_1>>v_i:=v_i+1;IFv_i<=100THENv_s:=v_s+v_i;GOTOlabel_1;ENDIF;DBMS_OUTPUT.PUT_LINE('1~100自然數(shù)之和:'||v_s);END;7.2PL/SQL程序結(jié)構(gòu)【例7.11】利用GOTO語7.2PL/SQL程序結(jié)構(gòu)7.2.4NULL結(jié)構(gòu)NULL語句是一個(gè)空操作的執(zhí)行語句,通過執(zhí)行NULL語句,可以直接將控制傳遞到下一條語句,以提高PL/SQL塊的可讀性?!纠?.12】根據(jù)輸入的學(xué)生學(xué)號(hào)和課程號(hào),從“成績(jī)表”中查找學(xué)生的課程成績(jī),如果成績(jī)低于60分,將“是否補(bǔ)考”字段的值修改為“是”,否則不執(zhí)行任何操作。

7.2PL/SQL程序結(jié)構(gòu)7.2.4NULL結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)

DECLARE

v_學(xué)號(hào)成績(jī)表.學(xué)號(hào)%TYPE;

v_課程號(hào)成績(jī)表.課程號(hào)%TYPE;

v_成績(jī)成績(jī)表.成績(jī)%TYPE;

BEGIN

v_學(xué)號(hào):='&學(xué)號(hào)';

v_課程號(hào):='&課程號(hào)';

SELECT成績(jī)INTOv_成績(jī)FROM成績(jī)表

WHERE學(xué)號(hào)=v_學(xué)號(hào)AND課程號(hào)=v_課程號(hào);

IFv_成績(jī)<60THEN

UPDATE成績(jī)表SET是否補(bǔ)考='是'

WHERE學(xué)號(hào)=v_學(xué)號(hào)AND課程號(hào)=v_課程號(hào);

DBMS_OUTPUT.PUT_LINE(v_學(xué)號(hào)||'號(hào)學(xué)生'||v_課程號(hào)||'號(hào)課程'||'成績(jī)?yōu)椋?/p>

'||v_成績(jī)||'需要補(bǔ)考');

ELSE

NULL;

ENDIF;

END;思考:如何對(duì)表中所有數(shù)據(jù)進(jìn)行判斷并設(shè)置補(bǔ)考信息?7.2PL/SQL程序結(jié)構(gòu)DECLARE7.3異常處理注意:commit語句7.3異常處理在語句執(zhí)行過程中,因?yàn)楦鞣N原因是的語句不能正常執(zhí)行時(shí),就有可能造成更大錯(cuò)誤或整個(gè)系統(tǒng)的崩潰,所以應(yīng)該采取必要的措施來防止這種情況的發(fā)生。PL/SQL提供了異常這一處理錯(cuò)誤情況的方法。在PL/SQL代碼部分執(zhí)行的過程中無論何時(shí)發(fā)生錯(cuò)誤,控制將自動(dòng)轉(zhuǎn)向執(zhí)行異常部分。PL/SQL有三種異常:系統(tǒng)預(yù)定義異常、非預(yù)定義異常和用戶自定義異常。7.3異常處理注意:commit語句7.3異常處理7.3.1系統(tǒng)預(yù)定義異常系統(tǒng)預(yù)定義異常處理是針對(duì)PL/SQL程序編譯、執(zhí)行過程中發(fā)生的問題進(jìn)行處理的程序,當(dāng)一段PL/SQL程序違反Oracle規(guī)則或是超出系統(tǒng)特定限制時(shí)就會(huì)引發(fā)異常。例如,如果SELECTINTO語句沒有返回記錄,或者在已經(jīng)達(dá)到結(jié)果集末尾的情況下,Oracle將激活預(yù)定義異常NO_DATA_FOUND。系統(tǒng)中預(yù)定義的異常如表7-9所示。7.3異常處理7.3.1系統(tǒng)預(yù)定義異常7.3異常處理系統(tǒng)預(yù)定義異常的拋出和處理的語法格式如下:EXCEPTIONWHEN異常名1[OR異常名2…]THEN

異常處理段1;[WHEN異常名3[OR異常名4…]THEN

異常處理段2;[WHENOTHERSTHEN

異常處理段3;]]7.3異常處理系統(tǒng)預(yù)定義異常的拋出和處理的語法格式如下:7.3異常處理【例7.13】根據(jù)輸入的學(xué)生姓名,在“學(xué)生表”中查找并輸出其相關(guān)信息,如果不存在該學(xué)生,進(jìn)行異常處理。代碼如下:7.3異常處理【例7.13】根據(jù)輸入的學(xué)生姓名,在“學(xué)生7.3異常處理DECLAREv_學(xué)號(hào)學(xué)生表.學(xué)號(hào)%TYPE;v_性別學(xué)生表.性別%TYPE;v_入學(xué)時(shí)間學(xué)生表.入學(xué)時(shí)間%TYPE;BEGINSELECT學(xué)號(hào),性別,入學(xué)時(shí)間INTOv_學(xué)號(hào),v_性別,v_入學(xué)時(shí)間FROM學(xué)生表WHERE姓名='&姓名';DBMS_OUTPUT.PUT_LINE('學(xué)號(hào):'||v_學(xué)號(hào));DBMS_OUTPUT.PUT_LINE('性別:'||v_性別);DBMS_OUTPUT.PUT_LINE('入學(xué)時(shí)間:'||v_入學(xué)時(shí)間);EXCEPTION WHENNO_DATA_FOUNDTHENDBMS_OUTPUT.PUT_LINE('沒有該學(xué)生!');END;作業(yè)二、用%ROWTYPE完成上述問題。7.3異常處理DECLARE7.3異常處理7.3.2非預(yù)定義異常預(yù)定義異常只能用于處理21種Oracle系統(tǒng)異常,而PL/SQL塊運(yùn)行時(shí)可能還會(huì)遭遇其他Oracle異常,為了提高PL/SQL程序塊的健壯性,系統(tǒng)提供了非預(yù)定義異常,用于處理與預(yù)定義異常無關(guān)的Oracle異常。非預(yù)定義異常處理步驟如下:在聲明部分,用EXCEPTION類型定義異常的名稱。在聲明部分,使用EXCEPTION_INIT編譯指令建立該異常名稱與某個(gè)Oracle異常的關(guān)聯(lián)。當(dāng)該Oracle異常發(fā)生時(shí),就會(huì)自動(dòng)進(jìn)行處理。在異常處理部分,處理異常。7.3異常處理7.3.2非預(yù)定義異常7.3異常處理EXCEPTION_INIT的語法格式為:PRAGMAEXCEPTION_INIT(exception_name,oracle_error_code)其中:exception_name是定義的異常名稱;oracle_error_code是Oracle的異常代碼。7.3異常處理EXCEPTION_INIT的語法格式為:7.3異常處理【例7.14】“學(xué)生表”中學(xué)號(hào)字段不允許為空,當(dāng)插入一個(gè)空值時(shí),系統(tǒng)會(huì)產(chǎn)生錯(cuò)誤代碼為-1400(-01400)的異常,對(duì)這個(gè)錯(cuò)誤進(jìn)行異常處理的代碼如下:

DECLARE

e_null_errorEXCEPTION;

pragmaEXCEPTION_INIT(e_null_error,-1400);

BEGIN

INSERTINTO學(xué)生表VALUES(NULL,'張健','男','12-3月-1987','18-9月-2006','保定市','060101001');

EXCEPTION

WHENe_null_errorTHEN

DBMS_OUTPUT.PUT_LINE('不能向?qū)W號(hào)列插入NULL');

END;7.3異常處理【例7.14】“學(xué)生表”中學(xué)號(hào)字段不允許為7.3異常處理7.3.3自定義異常自定義異常是由PL/SQL程序員定義的異常,它并不一定是一個(gè)錯(cuò)誤,而是程序員根據(jù)編程和調(diào)試的需要而為特殊情況所定義的異常。自定義異常必須要聲明,并且用RAISE語句觸發(fā)異常,使用自定義異常的步驟如下:在聲明部分,用EXCEPTION類型定義異常錯(cuò)誤的名稱。在執(zhí)行部分,當(dāng)出現(xiàn)異常情況時(shí),使用RAISE語句觸發(fā)異常。在異常處理部分,處理異常錯(cuò)誤。7.3異常處理7.3.3自定義異常7.3異常處理【例7.15】根據(jù)學(xué)號(hào)統(tǒng)計(jì)學(xué)生某學(xué)期選課門數(shù),如果選課超過3門,則提示異常信息。代碼如下:7.3異常處理【例7.15】根據(jù)學(xué)號(hào)統(tǒng)計(jì)學(xué)生某學(xué)期選課門DECLAREv_學(xué)號(hào)選課表.學(xué)號(hào)%TYPE;v_學(xué)年學(xué)期選課表.學(xué)年學(xué)期%TYPE;v_countNUMBER;e_lesson_errorEXCEPTION;BEGINv_學(xué)號(hào):='&學(xué)號(hào)';v_學(xué)年學(xué)期:='&學(xué)年學(xué)期';SELECTcount(*)INTOv_countFROM選課表WHERE學(xué)號(hào)=v_學(xué)號(hào)and學(xué)年學(xué)期=v_學(xué)年學(xué)期;IFv_count>3THENRAISE

e_lesson_error;ELSEDBMS_OUTPUT.PUT_LINE(v_學(xué)號(hào)||'號(hào)學(xué)生'||v_學(xué)年學(xué)期||'學(xué)期選課'||v_count||'門,選課正常。');ENDIF;EXCEPTIONWHENe_lesson_errorTHENDBMS_OUTPUT.PUT_LINE(v_學(xué)號(hào)||'號(hào)學(xué)生'||v_學(xué)年學(xué)期||'學(xué)期選課'||v_count||'門,超過3門。');END;作業(yè):用其他方法實(shí)現(xiàn)上述問題。DECLARE第7章PL/SQL編程第7章PL/SQL編程PL/SQL編程7.1PL/SQL語言基礎(chǔ)7.2PL/SQL程序結(jié)構(gòu)7.3異常處理PL/SQL編程7.1PL/SQL語言基礎(chǔ)7.1PL/SQL語言基礎(chǔ)7.1.1PL/SQL語言優(yōu)點(diǎn)PL/SQL是一種高效的事務(wù)處理語言,它具備以下優(yōu)點(diǎn):PL/SQL是一種高性能的基于事務(wù)處理的語言,能運(yùn)行在任何Oracle環(huán)境中,支持所有數(shù)據(jù)處理命令。通過使用PL/SQL程序單元處理SQL的數(shù)據(jù)定義和數(shù)據(jù)控制元素。PL/SQL支持所有SQL數(shù)據(jù)類型和所有SQL函數(shù),同時(shí)支持所有Oracle對(duì)象類型。PL/SQL塊可以被命名并存儲(chǔ)在Oracle服務(wù)器中,同時(shí)也能被其他PL/SQL程序或SQL命令調(diào)用,任何客戶/服務(wù)器工具都能訪問PL/SQL程序,具有很好的可重用性??梢允褂肙racle數(shù)據(jù)工具管理PL/SQL程序的安全性。可以授權(quán)或撤銷數(shù)據(jù)庫(kù)其他用戶訪問PL/SQL程序權(quán)限。7.1PL/SQL語言基礎(chǔ)7.1.1PL/SQL語言7.1PL/SQL語言基礎(chǔ)PL/SQL代碼可以使用任何ASCII文本編輯器編寫,所以對(duì)任何能夠運(yùn)行Oracle的操作系統(tǒng)都是非常便利的。對(duì)于SQL,Oracle必須在同一時(shí)間處理每一條SQL語句,在網(wǎng)絡(luò)環(huán)境下這就意味著每一個(gè)獨(dú)立的調(diào)用都必須被Oracle服務(wù)器處理,從而占用大量的服務(wù)器時(shí)間,導(dǎo)致網(wǎng)絡(luò)擁擠。而PL/SQL以整個(gè)語句塊形式發(fā)給服務(wù)器,可以減少網(wǎng)絡(luò)擁擠。7.1PL/SQL語言基礎(chǔ)PL/SQL代碼可以使用任何7.1PL/SQL語言基礎(chǔ)7.1.2PL/SQL的基本結(jié)構(gòu)一個(gè)PL/SQL程序包含一個(gè)或多個(gè)邏輯塊,每個(gè)塊都可以劃分為三個(gè)部分:聲明部分(用DECLARE開頭)、執(zhí)行部分(以BEGIN開頭)和異常處理部分(以EXCEPTION開頭)

1、PL/SQL基本結(jié)構(gòu)如下:

DECLARE

聲明部分

BEGIN

執(zhí)行部分

EXCEPTION

異常處理部分

END;7.1PL/SQL語言基礎(chǔ)7.1.2PL/SQL的基7.1PL/SQL語言基礎(chǔ)其中:聲明部分:定義變量和常量的數(shù)據(jù)類型和初始值,以及程序中要使用的函數(shù)、游標(biāo)、異常處理名稱等。如果沒有需要聲明的內(nèi)容,可以省略這一部分。PL/SQL中要使用的所有定義都必須在這一部分進(jìn)行集中定義。執(zhí)行部分:此部分是PL/SQL塊中的指令部分,所有的可執(zhí)行語句都放在這一部分,包括對(duì)數(shù)據(jù)庫(kù)的操作語句和各種流程控制語句,也可以嵌套其他的PL/SQL塊。執(zhí)行部分至少包含一條可執(zhí)行語句。異常處理部分:包含在執(zhí)行部分中,以關(guān)鍵字EXCEPTION開始,到END結(jié)束。當(dāng)程序檢測(cè)到錯(cuò)誤而產(chǎn)生異常時(shí),就轉(zhuǎn)到由EXCEPTION標(biāo)識(shí)的部分執(zhí)行異常處理程序。這部分是可選的,利用異常處理可以提高PL/SQL程序的健壯性。7.1PL/SQL語言基礎(chǔ)其中:7.1PL/SQL語言基礎(chǔ)2、

PL/SQL的特殊結(jié)構(gòu)

<<BLOCK1>>/*以名字標(biāo)識(shí)PL/SQL塊*/DECLARE

聲明部分BEGIN

執(zhí)行部分EXCEPTION

異常處理部分END<<BLOCK1>>;DECLARE

主塊聲明部分BEGIN

主塊執(zhí)行部分

DECLARE

子塊聲明部分

BEGIN

子塊執(zhí)行部分

EXCEPTION

子塊異常處理部分

END;EXCEPTION

主塊異常處理部分END;帶命名塊的PL/SQL塊嵌套結(jié)構(gòu)的PL/SQL塊7.1PL/SQL語言基礎(chǔ)2、PL/SQL的特殊結(jié)構(gòu)7.1PL/SQL語言基礎(chǔ)7.1.3PL/SQL的字符集1、合法字符,包括:大寫字母A-Z和小寫字母a-z數(shù)字0-9符號(hào)()、+、-、*、/、<、>、=、!、~、^、;、:、.、’、@、”、#、$、_、{}、[]、?制表符、空格符、回車符等非顯示的間空符號(hào)2、操作符,包括:算術(shù)操作符關(guān)系操作符邏輯操作符3、其他字符7.1PL/SQL語言基礎(chǔ)7.1.3PL/SQL的字7.1PL/SQL語言基礎(chǔ)7.1.4PL/SQL基本語法1、常量與變量的聲明,語法格式如下:

<常(變)量名>[CONSTANT]<數(shù)據(jù)類型>[NOTNULL][(寬度):=<初始值>]

【例7.1】幾個(gè)聲明的例子①聲明一個(gè)長(zhǎng)度為10B的變量count,初值為1,類型為VARCHAR2。

cvarchar2(10):='1';②聲明一個(gè)NUMBER數(shù)據(jù)類型的常量c_limit,并賦予初值5000.00。

c_limitconstantnumber(8.2):=5000.00;③聲明一個(gè)NUMBER數(shù)據(jù)類型的常量c_area,并用表達(dá)式給它賦初值。

c_areaconstantnumber(8.5):=3.14159*3**2;7.1PL/SQL語言基礎(chǔ)7.1.4PL/SQL基本7.1PL/SQL語言基礎(chǔ)2、作用域變量的作用域指變量的有效使用范圍,它從變量聲明開始,直到當(dāng)前程序塊結(jié)束,只有在其作用域范圍內(nèi),程序才能使用該變量,否則將導(dǎo)致編譯錯(cuò)誤。在同一程序塊中,不允許聲明兩個(gè)同名變量,但在不同程序塊內(nèi)可以聲明兩個(gè)同名變量。在程序塊內(nèi)聲明的變量稱為局部變量,在程序塊外聲明的變量稱為全局變量。引用程序塊內(nèi)的局部變量不需要加限定詞,而引用塊外的全局變量需要加限定詞(即父塊的名稱)。子塊中可以引用父塊的變量,但是父塊中不能引用子塊的變量。如果父塊與子塊具有相同的變量名,在子塊中引用這個(gè)變量時(shí)若是不加限定詞則引用的是子塊內(nèi)的局部變量。若兩個(gè)塊不是父子關(guān)系,則他們之間的變量不能相互引用。7.1PL/SQL語言基礎(chǔ)2、作用域7.1PL/SQL語言基礎(chǔ)(3)變量的屬性變量有名字和數(shù)據(jù)類型兩個(gè)屬性。變量名用于標(biāo)識(shí)該變量,變量的數(shù)據(jù)類型確定了該變量存放值的格式及允許的運(yùn)算。在PL/SQL中,使用“%”表示屬性提示符,后面緊跟屬性名。%TYPE和%ROWTYPE是PL/SQL中兩個(gè)特殊的屬性,常用來定義變量,使被定義變量的數(shù)據(jù)類型與一個(gè)已定義變量(或參照表中的記錄)的數(shù)據(jù)類型相一致。%TYPE使用%TYPE屬性定義變量時(shí),被定義變量的數(shù)據(jù)類型與一個(gè)已經(jīng)定義了的變量的數(shù)據(jù)類型相一致,當(dāng)被參照的變量數(shù)據(jù)類型改變后,新定義變量的數(shù)據(jù)類型也隨之改變。當(dāng)無法準(zhǔn)確知道被參照變量的數(shù)據(jù)類型時(shí),只能采用這種定義方法。定義格式為:<新變量名><被參照表.被參照列>%TYPE7.1PL/SQL語言基礎(chǔ)(3)變量的屬性7.1PL/SQL語言基礎(chǔ)【例7.1】聲明三個(gè)變量“v_班級(jí)名稱”,“v_班級(jí)人數(shù)”,“v_班主任”,其數(shù)據(jù)類型分別對(duì)應(yīng)“班級(jí)表”中相應(yīng)字段的數(shù)據(jù)類型。根據(jù)輸入的班級(jí)代碼,輸出對(duì)應(yīng)的班級(jí)名稱、人數(shù)和班主任信息。代碼如下:DECLAREv_班級(jí)名稱班級(jí)表.班級(jí)名稱%TYPE;v_班級(jí)人數(shù)班級(jí)表.班級(jí)人數(shù)%TYPE;v_班主任班級(jí)表.班主任%TYPE;BEGINSELECT班級(jí)名稱,班級(jí)人數(shù),班主任intov_班級(jí)名稱,v_班級(jí)人數(shù),v_班主任FROM班級(jí)表WHERE班級(jí)代碼='&班級(jí)代碼';DBMS_OUTPUT.PUT_LINE('班級(jí)名稱:'||v_班級(jí)名稱);DBMS_OUTPUT.PUT_LINE('班級(jí)人數(shù):'||v_班級(jí)人數(shù));DBMS_OUTPUT.PUT_LINE('班主任:'||v_班主任);END;語句:Setserverouton7.1PL/SQL語言基礎(chǔ)【例7.1】聲明三個(gè)變量“v7.1PL/SQL語言基礎(chǔ)%ROWTYPE使用%ROWTYPE屬性能夠定義記錄變量,使得被定義的記錄成員個(gè)數(shù)、名稱、數(shù)據(jù)類型與已定義的表或視圖中列的個(gè)數(shù)、名稱和數(shù)據(jù)類型完全相同。這種定義方式,可以定義一個(gè)表,當(dāng)被參照表中列及數(shù)據(jù)類型改變時(shí),新定義表中的列及數(shù)據(jù)類型自動(dòng)改變。當(dāng)一個(gè)表有較多列時(shí),使用%ROWTYPE定義記錄,比使用%TYPE要方便,并且不容易出錯(cuò)。定義格式為:<新表名><被參照表>%ROWTYPE7.1PL/SQL語言基礎(chǔ)%ROWTYPE7.1PL/SQL語言基礎(chǔ)【例7.2】聲明一個(gè)變量“v_班級(jí)”,與班級(jí)表具有相同的數(shù)據(jù)類型。根據(jù)輸入的班級(jí)代碼,輸出對(duì)應(yīng)的班級(jí)名稱、人數(shù)和班主任信息。代碼如下:DECLAREv_班級(jí)班級(jí)表%ROWTYPE;BEGINSELECT*intov_班級(jí)

FROM班級(jí)表WHERE班級(jí)代碼='&班級(jí)代碼';DBMS_OUTPUT.PUT_LINE('班級(jí)名稱:'||v_班級(jí).班級(jí)名稱);DBMS_OUTPUT.PUT_LINE('班級(jí)人數(shù):'||v_班級(jí).班級(jí)人數(shù));DBMS_OUTPUT.PUT_LINE('班主任:'||v_班級(jí).班主任);END;7.1PL/SQL語言基礎(chǔ)【例7.2】聲明一個(gè)變量“v7.1PL/SQL語言基礎(chǔ)3、數(shù)據(jù)類型標(biāo)量類型LOB型數(shù)據(jù)類型定義的運(yùn)算符7.1PL/SQL語言基礎(chǔ)3、數(shù)據(jù)類型7.1PL/SQL語言基礎(chǔ)【例7.3】聲明一個(gè)TIMESTAMP類型的變量,并為它賦值。代碼如下:SETSERVEROUTONDECLAREcheckoutTIMESTAMP(2);BEGINcheckout:='10-6月-07075';DBMS_OUTPUT.PUT_LINE(checkout);END;7.1PL/SQL語言基礎(chǔ)【例7.3】聲明一個(gè)TIME7.2PL/SQL程序結(jié)構(gòu)7.2.1選擇結(jié)構(gòu)選擇結(jié)構(gòu)又稱條件控制,通過先測(cè)試一個(gè)條件,根據(jù)測(cè)試結(jié)果選擇運(yùn)行不同的語句段。選擇結(jié)構(gòu)允許嵌套執(zhí)行。選擇結(jié)構(gòu)常用到的4種語法格式:IF…THEN…ENDIF結(jié)構(gòu)IF…THEN…ELSE…ENDIF結(jié)構(gòu)IF…THEN…ELSIF…ENDIF結(jié)構(gòu)CASE結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)7.2.1選擇結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)【例7.4】查找“ASP.NET程序設(shè)計(jì)”課程,若是“備注”信息為“C#”,將其改為“J#”,否則將“備注”信息置空。7.2PL/SQL程序結(jié)構(gòu)【例7.4】查找“ASP.N7.2PL/SQL程序結(jié)構(gòu)

DECLARE

v_課程課程表%ROWTYPE;

BEGIN

SELECT*INTOv_課程FROM課程表

WHERE課程名='ASP.NET程序設(shè)計(jì)';

IFv_課程.備注='C#'THEN

UPDATE課程表

SET備注='J#'

WHERE課程名=v_課程.課程名;

ELSE

UPDATE課程表

SET備注=''

WHERE課程名=v_課程.課程名;

ENDIF;

DBMS_OUTPUT.PUT_LINE('更新完成!');

END;

試一試:數(shù)據(jù)被修改了嗎?為什么?作業(yè)一、用你熟悉的方法完成該問題,比較兩種方法。7.2PL/SQL程序結(jié)構(gòu)DECLARE7.2PL/SQL程序結(jié)構(gòu)【例7.5】學(xué)生成績(jī)按照分?jǐn)?shù)段分為“優(yōu)秀”、“良好”、“合格”、“不及格”4種等級(jí),根據(jù)等級(jí)的不同,可以輸出對(duì)應(yīng)的分?jǐn)?shù)段,代碼如下:DECLAREv_resultVARCHAR2(20):='良好';BEGINIFv_result='優(yōu)秀'THENDBMS_OUTPUT.PUT_LINE('90~100');ELSIFv_result='良好'THENDBMS_OUTPUT.PUT_LINE('80~89');ELSIFv_result='合格'THENDBMS_OUTPUT.PUT_LINE('60~79');ELSIFv_result='不及格'THENDBMS_OUTPUT.PUT_LINE('<60');ELSEDBMS_OUTPUT.PUT_LINE('不存在該等級(jí)');ENDIF;END;7.2PL/SQL程序結(jié)構(gòu)【例7.5】學(xué)生成績(jī)按照分?jǐn)?shù)7.2PL/SQL程序結(jié)構(gòu)【例7.6】從“成績(jī)表”中根據(jù)學(xué)生的學(xué)號(hào)和課程號(hào)查找學(xué)生某門課程的成績(jī),并輸出成績(jī)的等級(jí)。采用CASE語法格式:7.2PL/SQL程序結(jié)構(gòu)【例7.6】從“成績(jī)表”中根7.2PL/SQL程序結(jié)構(gòu)DECLAREv_scoreNUMBER(3);BEGINSELECT成績(jī)intov_scoreFROM成績(jī)表WHERE學(xué)號(hào)=&學(xué)號(hào)and課程號(hào)=&課程號(hào);CASEWHEN(v_score>=90andv_score<=100)THENDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'優(yōu)秀');WHEN(v_score>=80andv_score<90)THENDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'良好');WHEN(v_score>=60andv_score<80)THENDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'合格');WHEN(v_score>=0andv_score<60)THENDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'不及格');ELSEDBMS_OUTPUT.PUT_LINE('成績(jī):'||v_score||'成績(jī)異常');ENDCASE;END;7.2PL/SQL程序結(jié)構(gòu)DECLARE7.2PL/SQL程序結(jié)構(gòu)【例7.7】使用CASE語句完成例7.5程序。要求使用CASE語句第二種語法格式實(shí)現(xiàn),代碼如下:DECLAREv_resultVARCHAR2(20):='良好';BEGINCASEv_resultWHEN'優(yōu)秀'THENDBMS_OUTPUT.PUT_LINE('90~100');WHEN'良好'THENDBMS_OUTPUT.PUT_LINE('80~89');WHEN'合格'THENDBMS_OUTPUT.PUT_LINE('60~79');WHEN'不及格'THENDBMS_OUTPUT.PUT_LINE('<60');ELSEDBMS_OUTPUT.PUT_LINE('不存在該等級(jí)');ENDCASE;END;7.2PL/SQL程序結(jié)構(gòu)【例7.7】使用CASE語句7.2PL/SQL程序結(jié)構(gòu)7.2.2循環(huán)結(jié)構(gòu)循環(huán)結(jié)構(gòu)可以對(duì)一段語句反復(fù)執(zhí)行,直到滿足某一條件,跳出循環(huán)

。循環(huán)結(jié)構(gòu)常用到的3種語法格式:LOOP…ENDLOOP結(jié)構(gòu)WHILE…LOOP…ENDLOOP結(jié)構(gòu)FOR…LOOP…ENDLOOP結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)7.2.2循環(huán)結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)【例7.8】利用LOOP循環(huán)和EXIT語句計(jì)算1至100的自然數(shù)之和。代碼如下:DECLAREv_iNUMBER:=1;v_sNUMBER:=0;BEGINLOOPEXITWHENv_i>100;v_s:=v_s+v_i;v_i:=v_i+1;ENDLOOP;DBMS_OUTPUT.PUT_LINE('1~100自然數(shù)之和:'||v_s);END;7.2PL/SQL程序結(jié)構(gòu)【例7.8】利用LOOP循環(huán)7.2PL/SQL程序結(jié)構(gòu)【例7.9】利用WHILE循環(huán)計(jì)算1至100的自然數(shù)之和。代碼如下:DECLAREv_iNUMBER:=0;v_sNUMBER:=0;BEGINWHILEv_i<=100LOOPv_s:=v_s+v_i;v_i:=v_i+1;ENDLOOP;DBMS_OUTPUT.PUT_LINE('1~100自然數(shù)之和:'||v_s);END;7.2PL/SQL程序結(jié)構(gòu)【例7.9】利用WHILE循7.2PL/SQL程序結(jié)構(gòu)【例7.10】利用FOR循環(huán)語句計(jì)算1至100的自然數(shù)之和。代碼如下:DECLAREv_sNUMBER:=0;BEGINFORv_iIN1..100LOOPv_s:=v_s+v_i;ENDLOOP;DBMS_OUTPUT.PUT_LINE('1~100自然數(shù)之和:'||v_s);END;思考題:如何利用循環(huán)語句生成數(shù)據(jù)?7.2PL/SQL程序結(jié)構(gòu)【例7.10】利用FOR循環(huán)7.2PL/SQL程序結(jié)構(gòu)7.2.3順序結(jié)構(gòu)順序結(jié)構(gòu)是一種最簡(jiǎn)單的控制結(jié)構(gòu),程序按語句順序依次執(zhí)行。有時(shí)為了打破執(zhí)行順序,將當(dāng)前程序跳轉(zhuǎn)到另一個(gè)地方繼續(xù)運(yùn)行,需要借助GOTO語句。GOTO語句是一種無條件跳轉(zhuǎn)語句,能夠?qū)⒄Z句無條件地跳轉(zhuǎn)到一個(gè)用標(biāo)簽指定的語句,其目的地必須與GOTO語句在同一程序塊中或更高層次(比如父塊中)中。但過多的使用GOTO語句會(huì)導(dǎo)致程序復(fù)雜,破壞程序的結(jié)構(gòu)。因此,GOTO語句一般只用在從一個(gè)PL/SQL塊中跳轉(zhuǎn)到異常處理語句的前面7.2PL/SQL程序結(jié)構(gòu)7.2.3順序結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)【例7.11】利用GOTO語句計(jì)算1至100的自然數(shù)之和。代碼如下:DECLAREv_iNUMBER:=0;v_sNUMBER:=0;BEGIN<<label_1>>v_i:=v_i+1;IFv_i<=100THENv_s:=v_s+v_i;GOTOlabel_1;ENDIF;DBMS_OUTPUT.PUT_LINE('1~100自然數(shù)之和:'||v_s);END;7.2PL/SQL程序結(jié)構(gòu)【例7.11】利用GOTO語7.2PL/SQL程序結(jié)構(gòu)7.2.4NULL結(jié)構(gòu)NULL語句是一個(gè)空操作的執(zhí)行語句,通過執(zhí)行NULL語句,可以直接將控制傳遞到下一條語句,以提高PL/SQL塊的可讀性。【例7.12】根據(jù)輸入的學(xué)生學(xué)號(hào)和課程號(hào),從“成績(jī)表”中查找學(xué)生的課程成績(jī),如果成績(jī)低于60分,將“是否補(bǔ)考”字段的值修改為“是”,否則不執(zhí)行任何操作。

7.2PL/SQL程序結(jié)構(gòu)7.2.4NULL結(jié)構(gòu)7.2PL/SQL程序結(jié)構(gòu)

DECLARE

v_學(xué)號(hào)成績(jī)表.學(xué)號(hào)%TYPE;

v_課程號(hào)成績(jī)表.課程號(hào)%TYPE;

v_成績(jī)成績(jī)表.成績(jī)%TYPE;

BEGIN

v_學(xué)號(hào):='&學(xué)號(hào)';

v_課程號(hào):='&課程號(hào)';

SELECT成績(jī)INTOv_成績(jī)FROM成績(jī)表

WHERE學(xué)號(hào)=v_學(xué)號(hào)AND課程號(hào)=v_課程號(hào);

IFv_成績(jī)<60THEN

UPDATE成績(jī)表SET是否補(bǔ)考='是'

WHERE學(xué)號(hào)=v_學(xué)號(hào)AND課程號(hào)=v_課程號(hào);

DBMS_OUTPUT.PUT_LINE(v_學(xué)號(hào)||'號(hào)學(xué)生'||v_課程號(hào)||'號(hào)課程'||'成績(jī)?yōu)椋?/p>

'||v_成績(jī)||'需要補(bǔ)考');

ELSE

NULL;

ENDIF;

END;思考:如何對(duì)表中所有數(shù)據(jù)進(jìn)行判斷并設(shè)置補(bǔ)考信息?7.2PL/SQL程序結(jié)構(gòu)DECLARE7.3異常處理注意:commit語句7.3異常處理在語句執(zhí)行過程中,因?yàn)楦鞣N原因是的語句不能正常執(zhí)行時(shí),就有可能造成更大錯(cuò)誤或整個(gè)系統(tǒng)的崩潰,所以應(yīng)該采取必要的措施來防止這種情況的發(fā)生。PL/SQL提供了異常這一處理錯(cuò)誤情況的方法。在PL/SQL代碼部分執(zhí)行的過程中無論何時(shí)發(fā)生錯(cuò)誤,控制將自動(dòng)轉(zhuǎn)向執(zhí)行異常部分。PL/SQL有三種異常:系統(tǒng)預(yù)定義異常、非預(yù)定義異常和用戶自定義異常。7.3異常處理注意:commit語句7.3異常處理7.3.1系統(tǒng)預(yù)定義異常系統(tǒng)預(yù)定義異常處理是針對(duì)PL/SQL程序編譯、執(zhí)行過程中發(fā)生的問題進(jìn)行處理的程序,當(dāng)一段PL/SQL程序違反Oracle規(guī)則或是超出系統(tǒng)特定限制時(shí)就會(huì)引發(fā)異常。例如,如果SELECTINTO語句沒有返回記錄,或者在已經(jīng)達(dá)到結(jié)果集末尾的情況下,Oracle將激活預(yù)定義異常NO_DATA_FOUND。系統(tǒng)中預(yù)定義的異常如表7-9所示。

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論