![第7章 游標(biāo)和異常處理_第1頁(yè)](http://file4.renrendoc.com/view8/M01/27/3F/wKhkGWcPp-GADZZSAADRBz0DCOo621.jpg)
![第7章 游標(biāo)和異常處理_第2頁(yè)](http://file4.renrendoc.com/view8/M01/27/3F/wKhkGWcPp-GADZZSAADRBz0DCOo6212.jpg)
![第7章 游標(biāo)和異常處理_第3頁(yè)](http://file4.renrendoc.com/view8/M01/27/3F/wKhkGWcPp-GADZZSAADRBz0DCOo6213.jpg)
![第7章 游標(biāo)和異常處理_第4頁(yè)](http://file4.renrendoc.com/view8/M01/27/3F/wKhkGWcPp-GADZZSAADRBz0DCOo6214.jpg)
![第7章 游標(biāo)和異常處理_第5頁(yè)](http://file4.renrendoc.com/view8/M01/27/3F/wKhkGWcPp-GADZZSAADRBz0DCOo6215.jpg)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第7章游標(biāo)和異常處理
第7章游標(biāo)和異常處理
7.1游標(biāo)的概念
7.2隱式游標(biāo)
7.3顯式游標(biāo)
7.4異常處理
75階段訓(xùn)練
7.6練習(xí)
第7章游標(biāo)和異常處理
7.1游標(biāo)的概念
游標(biāo)是SQL的一個(gè)內(nèi)存工作區(qū),由系統(tǒng)或用戶以變量
的形式定義。游標(biāo)的作用就是用于臨時(shí)存儲(chǔ)從數(shù)據(jù)庫(kù)中
提取的數(shù)據(jù)塊。在某些情況下,需要把數(shù)據(jù)從存放在磁
盤的表中調(diào)到計(jì)算機(jī)內(nèi)存中進(jìn)行處理,最后將處理結(jié)果
顯示出來(lái)或最終寫回?cái)?shù)據(jù)庫(kù)。這樣數(shù)據(jù)處理的速度才會(huì)
提高,否則頻繁的磁盤數(shù)據(jù)交換會(huì)降低效率。
第7章游標(biāo)和異常處理
游標(biāo)有兩種類型:顯式游標(biāo)和隱式游標(biāo)。在前述程
序中用到的SELECT…INTO…查詢語(yǔ)句,一次只能從數(shù)據(jù)
庫(kù)中提取一行數(shù)據(jù),對(duì)于這種形式的查詢和DML操作,
系統(tǒng)都會(huì)使用一個(gè)隱式游標(biāo)。但是如果要提取多行數(shù)據(jù),
就要由程序員定義一個(gè)顯式游標(biāo),并通過與游標(biāo)有關(guān)的
語(yǔ)句進(jìn)行處理。顯式游標(biāo)對(duì)應(yīng)一個(gè)返回結(jié)果為多行多列
的SELECT語(yǔ)句。
游標(biāo)一旦打開,數(shù)據(jù)就從數(shù)據(jù)庫(kù)中傳送到游標(biāo)變量
中,然后應(yīng)用程序再?gòu)挠螛?biāo)變量中分解出需要的數(shù)據(jù),
并進(jìn)行處理。
第7章游標(biāo)和異常處理
7.2隱式游標(biāo)
如前所述,DML操作和單行SELECT語(yǔ)句會(huì)使用隱
式游標(biāo),它們是:
*插入操作:INSERTo
*更新操作:UPDATEo
*刪除操作:DELETEo
*單行查詢操作:SELECT...INTO...o
第7章游標(biāo)和異常處理
當(dāng)系統(tǒng)使用一個(gè)隱式游標(biāo)時(shí),可以通過隱式游標(biāo)
的屬性來(lái)了解操作的狀態(tài)和結(jié)果,進(jìn)而控制程序的流
程。隱式游標(biāo)可以使用名字SQL來(lái)訪問,但要注意,
通過SQL游標(biāo)名總是只能訪問前一個(gè)DML操作或單行
SELECT操作的游標(biāo)屬性。所以通常在剛剛執(zhí)行完操作
之后,立即使用SQL游標(biāo)名來(lái)訪問屬性。游標(biāo)的屬性
有四種,如表7-1所示。
第7章游標(biāo)和異常處理
表7-1隱式游標(biāo)屬性
隱式游標(biāo)的屬性返回值類型意義
SQL%ROWCOUNT整型代表DML語(yǔ)句成功執(zhí)行的數(shù)據(jù)行數(shù)
值為TRUE代表插入、刪除、更新或單行查詢操作
SQL%FOUND布爾型
成功
SQL%NOTFOUND布爾型與SQL%FOUND屬性返回值相反
SQL%ISOPEN布爾型DML執(zhí)行過程中為真,結(jié)束后為假
第7章游標(biāo)和異常處理
【訓(xùn)練1】使用隱式游標(biāo)的屬性,判斷對(duì)雇員工
資的修改是否成功。
步驟1:輸入和運(yùn)行以下程序:
SETSERVEROUTPUTON
BEGIN
UPDATEempSETsal=sal+100WHEREempno=1234;
IFSQL%FOUNDTHEN
DBMS_OUTPUT.PUT_LINE(,成功修改雇員工資!,);
COMMIT;
ELSE
第7章游標(biāo)和異常處理
DBMSJDUTPUT.PUTJLINEC修改雇員工資失?。?,);
ENDIF;
END;
運(yùn)行結(jié)果為:
修改雇員工資失??!
PL/SQL過程已成功完成。
步驟2:將雇員編號(hào)1234改為7788,重新執(zhí)行以上程序:
運(yùn)行結(jié)果為:
成功修改雇員工資!
PL/SQL過程已成功完成。
說(shuō)明:本例中,通過SQL%FOUND屬性判斷修改是否成
功,并給出相應(yīng)信息。
第7章游標(biāo)和異常處理
7.3顯式游標(biāo)
7.3.1游標(biāo)的定義和操作
游標(biāo)的使用分成以下4個(gè)步驟。
1.聲明游標(biāo)
在DECLEAR部分按以下格式聲明游標(biāo):
CURSOR游標(biāo)名[(參數(shù)1數(shù)據(jù)類型[,參數(shù)2數(shù)據(jù)類
型…])]
ISSELECT語(yǔ)句;
參數(shù)是可選部分,所定義的參數(shù)可以出現(xiàn)在
SELECT語(yǔ)句的WHERE子句中。如果定義了參數(shù),則必
須在打開游標(biāo)時(shí)傳遞相應(yīng)的實(shí)際參數(shù)。
第7章游標(biāo)和異常處理
SELECT語(yǔ)句是對(duì)表或視圖的查詢語(yǔ)句,甚至也可
以是聯(lián)合查詢??梢詭HERE條件、ORDERBY或
GROUPBY等子句,但不能使用INTO子句。在
SELECT語(yǔ)句中可以使用在定義游標(biāo)之前定義的變量。
2.打開游標(biāo)
在可執(zhí)行部分,按以下格式打開游標(biāo):
OPEN游標(biāo)名[(實(shí)際參數(shù)1[,實(shí)際參數(shù)2...])];
打開游標(biāo)時(shí),SELECT語(yǔ)句的查詢結(jié)果就被傳送到
了游標(biāo)工作區(qū)。
第7章游標(biāo)和異常處理
3.提取數(shù)據(jù)
在可執(zhí)行部分,按以下格式將游標(biāo)工作區(qū)中的數(shù)據(jù)
取到變量中。提取操作必須在打開游標(biāo)之后進(jìn)行。
FETCH游標(biāo)名INTO變量名1[,變量名2...];
或
FETCH游標(biāo)名INTO記錄變量;
游標(biāo)打開后有一個(gè)指針指向數(shù)據(jù)區(qū),F(xiàn)ETCH語(yǔ)句一
次返回指針?biāo)傅囊恍袛?shù)據(jù),要返回多行需重復(fù)執(zhí)行,
可以使用循環(huán)語(yǔ)句來(lái)實(shí)現(xiàn)。控制循環(huán)可以通過判斷游標(biāo)
的屬性來(lái)進(jìn)行。
第7章游標(biāo)和異常處理
下面對(duì)這兩種格式進(jìn)行說(shuō)明:
第一種格式中的變量名是用來(lái)從游標(biāo)中接收數(shù)據(jù)
的變量,需要事先定義。變量的個(gè)數(shù)和類型應(yīng)與
SELECT語(yǔ)句中的字段變量的個(gè)數(shù)和類型一致。
第二種格式一次將一行數(shù)據(jù)取到記錄變量中,需
要使用%ROWTYPE事先定義記錄變量,這種形式使用
起來(lái)比較方便,不必分別定義和使用多個(gè)變量。
定義記錄變量的方法如下:
變量名表名|游標(biāo)名%ROWTYPE;
其中的表必須存在,游標(biāo)名也必須先定義。
第7章游標(biāo)和異常處理
4.關(guān)閉游標(biāo)
CLOSE游標(biāo)名;
顯式游標(biāo)打開后,必須顯式地關(guān)閉。游標(biāo)一旦關(guān)閉,游標(biāo)
占用的資源就被釋放,游標(biāo)變成無(wú)效,必須重新打開才能使用。
以下是使用顯式游標(biāo)的一個(gè)簡(jiǎn)單練習(xí)。
【訓(xùn)練1】用游標(biāo)提取emp表中7788雇員的名稱和職務(wù)。
SETSERVEROUTPUTON
DECLARE
venameVARCHAR2(10);
vjobVARCHAR2(10);
CURSORempcursorIS
SELECTenameJobFROMempWHEREempno=7788;
第7章游標(biāo)和異常處理
BEGIN
OPENempcursor;
FETCHempcursorINTOv_ename,vjob;
DBMS_OUTPUT.PUT_LINE(v_ename||7||vJob);
CLOSEempcursor;
END;
執(zhí)行結(jié)果為:
SCOTT,ANALYST
PL/SQL過程已成功完成。
說(shuō)明:該程序通過定義游標(biāo)emp_cursor,提取并顯示雇
員7788的名稱和職務(wù)。
作為對(duì)以上例子的改進(jìn),在以下訓(xùn)練中采用了記錄變量。
第7章游標(biāo)和異常處理
【訓(xùn)練2】用游標(biāo)提取emp表中7788雇員的姓名、
職務(wù)和工資。
SETSERVEROUTPUTON
DECLARE
CURSORempcursorISSELECTename,job,sal
FROMempWHEREempno=7788;
emprecordemp_cursor%ROWTYPE;
BEGIN
第7章游標(biāo)和異常處理
OPENempcursor;
FETCHempcursorINTOemprecord;
DBMS_OUTPUT.PUT_LINE(emp_record.ename||7
emp_record.job||7||emp_record.sal);
CLOSEempcursor;
END;
第7章游標(biāo)和異常處理
執(zhí)行結(jié)果為:
SCOTT,ANALYST,3000
PL/SQL過程已成功完成。
說(shuō)明:實(shí)例中使用記錄變量來(lái)接收數(shù)據(jù),記錄變
量由游標(biāo)變量定義,需要出現(xiàn)在游標(biāo)定義之后。
注意:可通過以下形式獲得記錄變量的內(nèi)容:
記錄變量名.字段名。
第7章游標(biāo)和異常處理
【訓(xùn)練3】顯示工資最高的前3名雇員的名稱和工
資。
SETSERVEROUTPUTON
DECLARE
VenameVARCHAR2(10);
V_salNUMBER(5);
CURSORempcursorISSELECTename,salFROM
empORDERBYsalDESC;
BEGIN
OPENempcursor;
FORIIN1..3LOOP
FETCHempcursorINTOv_ename,v_sal;
第7章游標(biāo)和異常處理
DBMS_OUTPUT.PUT_LINE(v_ename||7||v_sal);
ENDLOOP;
CLOSEempcursor;
END;
執(zhí)行結(jié)果為:
KING,5000
SCOTT,3000
FORD,3000
PL/SQL過程已成功完成。
說(shuō)明:該程序在游標(biāo)定義中使用了ORDERBY子
句進(jìn)行排序,并使用循環(huán)語(yǔ)句來(lái)提取多行數(shù)據(jù)。
第7章游標(biāo)和異常處理
7.3.2游標(biāo)循環(huán)
【訓(xùn)練1】使用特殊的FOR循環(huán)形式顯示全部雇
員的編號(hào)和名稱。
SETSERVEROUTPUTON
DECLARE
CURSORempcursorIS
SELECTempno,enameFROMemp;
BEGIN
第7章游標(biāo)和異常處理
FOREmprecordINempcursorLOOP
DBMS_OUTPUT.PUT_LINE(Emp_record.emp
no||Emprecord.ename);
ENDLOOP;
END;
第7章游標(biāo)和異常處理
執(zhí)行結(jié)果為:
7369SMITH
7499ALLEN
7521WARD
7566JONES
PL/SQL過程已成功完成。
說(shuō)明:可以看到該循環(huán)形式非常簡(jiǎn)單,隱含了記
錄變量的定義、游標(biāo)的打開、提取和關(guān)閉過程。
Empjecord為隱含定義的記錄變量,循環(huán)的執(zhí)行次數(shù)
與游標(biāo)取得的數(shù)據(jù)的行數(shù)相一致。
第7章游標(biāo)和異常處理
【訓(xùn)練2】另一種形式的游標(biāo)循環(huán)。
SETSERVEROUTPUTON
BEGIN
FORreIN(SELECTenameFROMEMP)LOOP
DBMSOUTPUT.PUTLINE(re.ename)
ENDLOOP;
END;
第7章游標(biāo)和異常處理
執(zhí)行結(jié)果為:
SMITH
ALLEN
WARD
JONES
說(shuō)明:該種形式更為簡(jiǎn)單,省略了游標(biāo)的定義,
游標(biāo)的SELECT查詢語(yǔ)句在循環(huán)中直接出現(xiàn)。
第7章游標(biāo)和異常處理
7.3.3顯式游標(biāo)屬性
雖然可以使用前面的形式獲得游標(biāo)數(shù)據(jù),但是在
游標(biāo)定義以后使用它的一些屬性來(lái)進(jìn)行結(jié)構(gòu)控制是一
種更為靈活的方法。顯式游標(biāo)的屬性如表7-2所示。
一
第7章游標(biāo)和異常處理
表7-2顯式游標(biāo)屬性
游標(biāo)的屬性返回值類型意義
%ROWCOUNT整型獲得FETCH語(yǔ)句返回的數(shù)據(jù)行數(shù)
%FOUND布爾型最近的FETCH語(yǔ)句返回一行數(shù)據(jù)則為真,否則為假
%NOTFOUND布爾型與%FOUND屬性返回值相反
%ISOPEN布爾型游標(biāo)已經(jīng)打開時(shí)值為真,否則為假
第7章游標(biāo)和異常處理
可按照以下形式取得游標(biāo)的屬性:
游標(biāo)名%屬性
要判斷游標(biāo)empcursor是否處于打開狀態(tài),可以使
用屬性emp_cursor%ISOPEN。如果游標(biāo)已經(jīng)打開,則返
回值為“真”,否則為“假”。具體可參照以下的訓(xùn)練。
第7章游標(biāo)和異常處理
【訓(xùn)練1】使用游標(biāo)的屬性練習(xí)。
SETSERVEROUTPUTON
DECLARE
VenameVARCHAR2(10);
CURSORempcursorIS
SELECTenameFROMemp;
BEGIN
OPENempcursor;
IFemp_cursor%ISOPENTHEN
第7章游標(biāo)和異常處理
LOOP
FETCHempcursorINTOvename;
EXITWHENemp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(to_char(emp_cursor
%ROWCOUNT)||,-,||v_ename);——
ENDLOOP;
ELSE
DBMS_OUTPUT.PUT_LINE(f用戶信息:游標(biāo)沒
有打開!力"
ENDIF;
CLOSEempcursor;
END;
第7章游標(biāo)和異常處理
執(zhí)行結(jié)果為:
1-SMITH
2-ALLEN
3-WARD
PL/SQL過程已成功完成。
說(shuō)明:本例使用emp_cursor%ISOPEN判斷游標(biāo)是否打開;
使用emp_cursor%ROWCOUNT獲得到目前為止FETCH語(yǔ)句返
回的數(shù)屆亍數(shù)并輸出;使用循環(huán)來(lái)獲取數(shù)據(jù),在循環(huán)體中使
用FETCH語(yǔ)句;使用emp_cursor%NOTFOUND^lJ斷FETCH語(yǔ)
句是否成功執(zhí)行,當(dāng)FETCH語(yǔ)句失敗時(shí)說(shuō)明數(shù)據(jù)已經(jīng)取完,
退出循環(huán)。
【練習(xí)1】去掉OPENemp_cursor;語(yǔ)句,重新執(zhí)行以上程
序。
第7章游標(biāo)和異常處理
7.3.4游標(biāo)參數(shù)的傳遞
【訓(xùn)練1】帶參數(shù)的游標(biāo)。
SETSERVEROUTPUTON
DECLARE
VempnoNUMBER(5);
VenameVARCHAR2(10);
CURSORemp_cursor(p_deptnoNUMBER,
pjobVARCHAR2)IS
SELECTempno,enameFROMemp
WHEREdeptno=pdeptnoANDjob=pjob;
第7章游標(biāo)和異常處理
BEGIN
OPENemp_cursor(10,^LERK1);
LOOP
FETCHempcursorINTOv_empno,v_ename;
EXITWHENemp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_empno||7||v_ename);
ENDLOOP;
END;
第7章游標(biāo)和異常處理
執(zhí)行結(jié)果為:
7934,MILLER
PL/SQL過程已成功完成。
說(shuō)明:游標(biāo)emp_cursor定義了兩個(gè)參數(shù):p_deptno代
表部門編號(hào),p」ob代表職務(wù)。語(yǔ)句OPENemp_cursor(10,
CLERK,)傳遞了兩個(gè)參數(shù)值給游標(biāo),即部門為10、職務(wù)為
CLERK,所以游標(biāo)查詢的內(nèi)容是部門10的職務(wù)為CLERK
的雇員。循環(huán)部分用于顯示查詢的內(nèi)容。
第7章游標(biāo)和異常處理
【練習(xí)1】修改Open語(yǔ)句的參數(shù):部門號(hào)為20、職
務(wù)為ANALYST,并重新執(zhí)行。
也可以通過變量向游標(biāo)傳遞參數(shù),但變量需要先
于游標(biāo)定義,并在游標(biāo)打開之前賦值。對(duì)以上例子重
新改動(dòng)如下:
【訓(xùn)練2】通過變量傳遞參數(shù)給游標(biāo)。
SETSERVEROUTPUTON
DECLARE
vempnoNUMBER(5);
venameVARCHAR2(10);
v_deptnoNUMBER(5);
第7章游標(biāo)和異常處理
vjobVARCHAR2(10);
CURSORempcursorIS
SELECTempno,enameFROMemp
WHEREdeptno=vdeptnoANDjob=vjob;
BEGIN
v_deptno:=10;
v」ob:='CLERK';
OPENempcursor;
LOOP
FETCHempcursorINTOvempno,vename;
EXITWHENemp_cursor%NOTFOUND;
第7章游標(biāo)和異常處理
DBMS_OUTPUT.PUT_LINE(v_empno||7||v_ename);
ENDLOOP;
END;
執(zhí)行結(jié)果為:
7934,MILLER
PL/SQL過程已成功完成。
說(shuō)明:該程序與前一程序?qū)崿F(xiàn)相同的功能。
第7章游標(biāo)和異常處理
7.3.5動(dòng)態(tài)SELECT語(yǔ)句和動(dòng)態(tài)游標(biāo)的用法
Oracle支持動(dòng)態(tài)SELECT語(yǔ)句和動(dòng)態(tài)游標(biāo),動(dòng)態(tài)的
方法大大擴(kuò)展了程序設(shè)計(jì)的能力。
對(duì)于查詢結(jié)果為一行的SELECT語(yǔ)句,可以用動(dòng)態(tài)
生成查詢語(yǔ)句字符串的方法,在程序執(zhí)行階段臨時(shí)地
生成并執(zhí)行,語(yǔ)法是:
executeimmediate查詢語(yǔ)句字符串into變量1[,變量
2...];
以下是一個(gè)動(dòng)態(tài)生成SELECT語(yǔ)句的例子。
第7章游標(biāo)和異常處理
【訓(xùn)練1】動(dòng)態(tài)SELECT查詢o
SETSERVEROUTPUTON
DECLARE
strvarchar2(100);
venamevarchar2(10);
begin
str:-selectenamefromscott.empwhereempno=7788';
executeimmediatestrintovename;
dbmsoutput.putline(vename);
END;
第7章游標(biāo)和異常處理
執(zhí)行結(jié)果為:
SCOTT
PL/SQL過程已成功完成。
說(shuō)明:SELECT…INTO…語(yǔ)句存放在STR字符串中,通
過EXECUTE語(yǔ)句執(zhí)行。
在變量聲明部分定義的游標(biāo)是靜態(tài)的,不能在程序運(yùn)
行過程中修改。雖然可以通過參數(shù)傳遞來(lái)取得不同的數(shù)據(jù),
但還是有很大的局限性。通過采用動(dòng)態(tài)游標(biāo),可以在程序
運(yùn)行階段隨時(shí)生成一個(gè)查詢語(yǔ)句作為游標(biāo)。要使用動(dòng)態(tài)游
標(biāo)需要先定義一個(gè)游標(biāo)類型,然后聲明一個(gè)游標(biāo)變量,游
標(biāo)對(duì)應(yīng)的查詢語(yǔ)句可以在程序的執(zhí)行過程中動(dòng)態(tài)地說(shuō)明。
第7章游標(biāo)和異常處理
定義游標(biāo)類型的語(yǔ)句如下:
TYPE游標(biāo)類型名REFCURSOR;
聲明游標(biāo)變量的語(yǔ)句如下:
游標(biāo)變量名游標(biāo)類型名;
在可執(zhí)行部分可以如下形式打開一個(gè)動(dòng)態(tài)游標(biāo):
OPEN游標(biāo)變量名FOR查詢語(yǔ)句字符串;
第7章游標(biāo)和異常處理
【訓(xùn)練2】按名字中包含的字母順序分組顯示雇
員信息。
輸入并運(yùn)行以下程序:
declare
typecurtypeisrefcursor;
curcurtype;
recscott.emp%rowtype;
strvarchar2(50);
letterchar:='A';
第7章游標(biāo)和異常處理
begin
loop
str:=’selectenamefromempwhereenamelike
n%,||letter||,%n,;
opencurforstr;
dbms_output.put_line(,包含字母[〔letter『的名字:*);
loop
fetchcurintorec.ename;
exitwhencur%notfbund;
dbms_output.put_line(rec.ename);
第7章游標(biāo)和異常處理
endloop;
exitwhenletter='Z';
letter:=chr(ascii(letter)+1);
endloop;
end;
運(yùn)行結(jié)果為:
包含字母A的名字:
ALLEN
WARD
MARTIN
..
第7章游標(biāo)和異常處理
BLAKE
CLARK
ADAMS
JAMES
包含字母B的名字
BLAKE
包含字母C的名字
CLARK
SCOTT
第7章游標(biāo)和異常處理
說(shuō)明:使用了二重循環(huán),在外循環(huán)體中,動(dòng)態(tài)生
成游標(biāo)的SELECT語(yǔ)句,然后打開。通過語(yǔ)句
letter:=chr(ascii(letter)+l)可獲得字母表中的下一個(gè)字母。
第7章游標(biāo)和異常處理
7.4異常處理
7.4.1錯(cuò)誤處理
錯(cuò)誤處理部分位于程序的可執(zhí)行部分之后,是由
WHEN語(yǔ)句引導(dǎo)的多個(gè)分支構(gòu)成的。錯(cuò)誤處理的語(yǔ)法
如下:
EXCEPTION
WHEN錯(cuò)誤1[OR錯(cuò)誤2]THEN
語(yǔ)句序列1;
WHEN錯(cuò)誤3[OR錯(cuò)誤4]THEN
第7章游標(biāo)和異常處理
語(yǔ)句序列2;
WHENOTHERS
語(yǔ)句序列n;
END;
其中:
錯(cuò)誤是在標(biāo)準(zhǔn)包中由系統(tǒng)預(yù)定義的標(biāo)準(zhǔn)錯(cuò)誤,或
是由用戶在程序的說(shuō)明部分自定義的錯(cuò)誤,參見下一
節(jié)系統(tǒng)預(yù)定義的錯(cuò)誤類型。
語(yǔ)句序列就是不同分支的錯(cuò)誤處理部分。
'、辿/%
7浙茲-
^4
第7章游標(biāo)和異常處理
凡是出現(xiàn)在WHEN后面的錯(cuò)誤都是可以捕捉到的
錯(cuò)誤,其他未被捕捉到的錯(cuò)誤,將在WHENOTHERS
部分進(jìn)行統(tǒng)一處理,OTHENS必須是EXCEPTION部分
的最后一個(gè)錯(cuò)誤處理分支。如要在該分支中進(jìn)一步判
斷錯(cuò)誤種類,可以通過使用預(yù)定義函數(shù)SQLCODE()和
SQLERRM()來(lái)獲得系統(tǒng)錯(cuò)誤號(hào)和錯(cuò)誤信息。
如果在程序的子塊中發(fā)生了錯(cuò)誤,但子塊沒有錯(cuò)
誤處理部分,則錯(cuò)誤會(huì)傳遞到主程序中。
下面是由于查詢編號(hào)錯(cuò)誤而引起系統(tǒng)預(yù)定義異常
的例子。
第7章游標(biāo)和異常處理
【訓(xùn)練1】查詢編號(hào)為1234的雇員名字。
SETSERVEROUTPUTON
DECLARE
vnameVARCHAR2(10);
BEGIN
SELECTename
INTOvname
FROMemp
WHEREempno=1234;
第7章游標(biāo)和異常處理
DBMS_OUTPUT.PUT_LINE(f該雇員名字為:!||
vname);
EXCEPTION
WHENNODATAFOUNDTHEN
DBMS_OUTPUT.PUT_LINE(,編號(hào)錯(cuò)誤,沒有找
到相應(yīng)雇員!,);
WHENOTHERSTHEN
DBMSJDUTPUT.PUTLINEC發(fā)生其他錯(cuò)誤!,);
END;
執(zhí)行結(jié)果為:
編號(hào)錯(cuò)誤,沒有找到相應(yīng)雇員!
PL/SQL過程已成功完成。
第7章游標(biāo)和異常處理
說(shuō)明:在以上查詢中,因?yàn)榫幪?hào)為1234的雇員不
存在,所以將發(fā)生類型為"NO_DATA_
FOUND〃的異常?!癗O_DATA_FOUND〃是系統(tǒng)
預(yù)定義的錯(cuò)誤類型,EXCEPTION部分下的WHEN語(yǔ)句
將捕捉到該異常,并執(zhí)行相應(yīng)代碼部分。在本例中,
輸出用戶自定義的錯(cuò)誤信息“編號(hào)錯(cuò)誤,沒有找到相
應(yīng)雇員!〃。如果發(fā)生其他類型的錯(cuò)誤,將執(zhí)行
OTHERS條件下的代碼部分,顯示“發(fā)生其他錯(cuò)誤!〃。
第7章游標(biāo)和異常處理
【訓(xùn)練2】由程序代碼顯示系統(tǒng)錯(cuò)誤。
SETSERVEROUTPUTON
DECLARE
vtempNUMBER(5):=1;
BEGIN
vtemp:=vtemp/0;
EXCEPTION
WHENOTHERSTHEN
第7章游標(biāo)和異常處理
DBMSJ3UTPUT.PUTLINEC發(fā)生系統(tǒng)錯(cuò)誤!,);
DBMS_OUTPUT.PUT_LINE(,錯(cuò)誤代碼:1|SQLCODE());
DBMS_OUTPUT.PUT_LINE(,錯(cuò)誤信息:”|SQLERRM());
END;
執(zhí)行結(jié)果為:
發(fā)生系統(tǒng)錯(cuò)誤!
錯(cuò)誤代碼:?1476
錯(cuò)誤信息:ORA-01476:除數(shù)為0
PL/SQL過程已成功完成。
第7章游標(biāo)和異常處理
說(shuō)明:程序運(yùn)行中發(fā)生除零錯(cuò)誤,由WHENOTHERS捕
捉到,執(zhí)行用戶自己的輸出語(yǔ)句顯示錯(cuò)誤信息,然后正常結(jié)
束。在錯(cuò)誤處理部分使用了預(yù)定義函數(shù)SQLCODE()和
SQLERRM()來(lái)進(jìn)一步獲得錯(cuò)誤的代碼和種類信息。
7.4.2預(yù)定義錯(cuò)誤
Oracle的系統(tǒng)錯(cuò)誤很多,但只有一部分常見錯(cuò)誤在標(biāo)準(zhǔn)
包中予以定義。定義的錯(cuò)誤可以在EXCEPTION部分通過標(biāo)
準(zhǔn)的錯(cuò)誤名來(lái)進(jìn)行判斷,并進(jìn)行異常處理。常見的系統(tǒng)預(yù)定
義異常如表7-3所示。
第7章游標(biāo)和異常處理
表7-3系統(tǒng)預(yù)定義異常
錯(cuò)誤名稱錯(cuò)誤代碼錯(cuò)誤含義
CURSOR_ALREADY_OPENORA_06511試圖打開已經(jīng)打開的游標(biāo)
INVALID_CURSORORA_01001試圖使用沒有打開的游標(biāo)
DUP_VAL_ON_INDEXORA_00001保存重復(fù)值到惟一索引約束的列中
ZERO_DIVIDEORA_01476發(fā)生除數(shù)為零的除法錯(cuò)誤
INVALID_NUMBERORA_01722試圖對(duì)無(wú)效字符進(jìn)行數(shù)值轉(zhuǎn)換
ROWTYPE_MISMATCHORA_06504主變量和游標(biāo)的類型不兼容
VALUE_ERRORORA_06502轉(zhuǎn)換、截?cái)嗷蛩阈g(shù)運(yùn)算發(fā)生錯(cuò)誤
TOO_MANY_ROWSORA_01422SELECT...INTO…語(yǔ)句返回多于一行的數(shù)據(jù)
NO_DATA_FOUNDORA_01403SELECT...INTO…語(yǔ)句沒有數(shù)據(jù)返回
TIMEOUT_ON_RESOURCEORA_00051等待資源時(shí)發(fā)生超時(shí)錯(cuò)誤
TRANSACTION_BACKED_OUTORA_00060由于死鎖,提交失敗
STORAGE_ERRORORA_06500發(fā)生內(nèi)存錯(cuò)誤
PROGRAM_ERRORORA_06501發(fā)生PL/SQL內(nèi)部錯(cuò)誤
NOT_LOGGED_ONORA_01012試圖操作未連接的數(shù)據(jù)庫(kù)
LOG1N_DENIEDORA_01017在連接時(shí)提供了無(wú)效用戶名或口令
第7章游標(biāo)和異常處理
比如,如果程序向表的主鍵列插入重復(fù)值,則將發(fā)生
DUPVALONJNDEX錯(cuò)誤。
如果一個(gè)系統(tǒng)錯(cuò)誤沒有在標(biāo)準(zhǔn)包中定義,則需要在說(shuō)
明部分定義,語(yǔ)法如下:
錯(cuò)誤名EXCEPTION;
定義后使用PRAGMAEXCEPTIONJNIT來(lái)將一個(gè)定義
的錯(cuò)誤同一個(gè)特別的Oracle錯(cuò)誤代碼相關(guān)聯(lián),就可以同系
統(tǒng)預(yù)定義的錯(cuò)誤一樣使用了。語(yǔ)法如下:
PRAGMAEXCEPTION_INIT(錯(cuò)誤名,-錯(cuò)誤代碼);
第7章游標(biāo)和異常處理
【訓(xùn)練1】定義新的系統(tǒng)錯(cuò)誤類型。
SETSERVEROUTPUTON
DECLARE
V_ENAMEVARCHAR2(10);
NULLINSERTERROREXCEPTION;
PRAGMA
EXCEPTION_INIT(NULL_INSERT_ERROR,-1400);
BEGIN
INSERTINTOEMP(EMPNO)VALUES(NULL);
EXCEPTION
第7章游標(biāo)和異常處理
WHENNULLINSERTERRORTHEN
DBMS_OUTPUT.PUT_LINE(f無(wú)法插入NULL值!
');
WHENOTHERSTHEN
DBMS_OUTPUT.PUT_LINE(,發(fā)生其他系統(tǒng)錯(cuò)誤!
');
END;
執(zhí)行結(jié)果為:
無(wú)法插入NULL值!
PL/SQL過程已成功完成。
說(shuō)明:NULL」NSERT_ERROR是自定義異常,同
不統(tǒng)警1400相關(guān)聯(lián)。
第7章游標(biāo)和異常處理
7.4.3自定義異常
程序設(shè)計(jì)者可以利用引發(fā)異常的機(jī)制來(lái)進(jìn)行程序設(shè)計(jì),
自己定義異常類型。可以在聲明部分定義新的異常類型,
定義的語(yǔ)法是:
錯(cuò)誤名EXCEPTION;
用戶定義的錯(cuò)誤不能由系統(tǒng)來(lái)觸發(fā),必須由程序顯式
地觸發(fā),觸發(fā)的語(yǔ)法是:
RAISE錯(cuò)誤名;
第7章游標(biāo)和異常處理
RAISE也可以用來(lái)引發(fā)模擬系統(tǒng)錯(cuò)誤,比如,
RAISEZERO_DIVIDE將引發(fā)模擬的除零錯(cuò)誤。
使用RAISE_APPLICATION_ERROR函數(shù)也可以弓|
發(fā)異常。該函數(shù)要傳遞兩個(gè)參數(shù),第一個(gè)是用戶自定
義的錯(cuò)誤編號(hào),第二個(gè)參數(shù)是用戶自定義的錯(cuò)誤信息。
使用該函數(shù)引發(fā)的異常的編號(hào)應(yīng)該在20000和20999之
間選擇。
自定義異常處理錯(cuò)誤的方式同前。
第7章游標(biāo)和異常處理
【訓(xùn)練1】插入新雇員,限定插入雇員的編號(hào)在
7000?8000之間。
SETSERVEROUTPUTON
DECLARE
newnoNUMBER(IO);
newexcp1EXCEPTION;
new_excp2EXCEPTION;
BEGIN
第7章游標(biāo)和異常處理
new_no:=6789;
INSERTINTOemp(empno,ename)
VALUES(new_noJ小鄭)
IFnew_no<7000THEN
RAISEnewexcp1;
ENDIF;
IFnew_no>8000THEN
RAISEnew_excp2;
ENDIF;
COMMIT;
EXCEPTION
第7章游標(biāo)和異常處理
WHENnewexcplTHEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE(f>員編號(hào)小于7000的下限!
,);~~
WHENnew_excp2THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE(f>員編號(hào)超過8000的上限!
');
END;
執(zhí)行結(jié)果為:
雇員編號(hào)小于7000的下限!
PL/SQL過程已成功完成。
第7章游標(biāo)和異常處理
說(shuō)明:在此例中,自定義了兩個(gè)異常:newexcp1
和new_excp2,分別代表編號(hào)小于7000和編號(hào)大于8000
的錯(cuò)誤。在程序中通過判斷編號(hào)大小,產(chǎn)生對(duì)應(yīng)的異
常,并在異常處理部分回退插入操作,然后顯示相應(yīng)
的錯(cuò)誤信息。
^4
第7章游標(biāo)和異常處理
【訓(xùn)練2】使用RAISEAPPLICATIONERROR函
數(shù)引發(fā)系統(tǒng)異常。
SETSERVEROUTPUTON
DECLARE
NewnoNUMBER(IO);
BEGIN
New_no:=6789;
INSERTINTOemp(empno,ename)
VALUES(new_no,'JAMES');
第7章游標(biāo)和異常處理
IFnew_no<7000THEN
ROLLBACK;
RAISE_APPLICATION_ERROR(-20001,,編號(hào)小于
7000的下限!,);
ENDIF;
IFnew_no>8000THEN
ROLLBACK;
RAISEAPPLICATIONERROR(-20002」編號(hào)大于
8000的下限!
ENDIF;
END;
第7章游標(biāo)和異常處理
執(zhí)行結(jié)果為:
DECLARE
*
ERROR位于第1行:
ORA-20001:編號(hào)小于7000的下限!
ORA-06512:在line9
說(shuō)明:在本訓(xùn)練中,使用
RAISE_APPLICATION_ERROR引發(fā)自定義異常,并以系統(tǒng)
錯(cuò)誤的方式進(jìn)行顯示。錯(cuò)誤編號(hào)為20001和20002。
注意:同上一個(gè)訓(xùn)練比較,此種方法不需要事先定義異
常,可直接引發(fā)。
第7章游標(biāo)和異常處理
可以參考下面的程序片斷將出錯(cuò)信息記錄到表中,
其中,errors為記錄錯(cuò)誤信息的表,SQLCODE為發(fā)生
異常的錯(cuò)誤編號(hào),SQLERRM為發(fā)生異常的錯(cuò)誤信息。
DECLARE
verrorcodeNUMBER;
v_error_messageVARCHAR2(255);
BEGIN
EXCEPTION
第7章游標(biāo)和異常處理
WHENOTHERSTHEN
verrorcode:=SQLCODE;
v_error_message:=SQLERRM;
INSERTINTOerrors
VALUES(verrorcode,v_error_message);
END;
【練習(xí)1】修改雇員的工資,通過引發(fā)異常控制修
改范圍在600?6000之間。
第7章游標(biāo)和異常處理
7.5階段訓(xùn)練
【訓(xùn)練1】將雇員從一個(gè)表復(fù)制到另一個(gè)表。
步驟1:創(chuàng)建一個(gè)結(jié)構(gòu)同EMP表一樣的新表EMP1:
CREATETABLEemplASSELECT*FROM
SCOTT.EMPWHERE1=2;
步驟2:通過指定雇員編號(hào),將雇員由EMP表移動(dòng)
到EMP1表:
第7章游標(biāo)和異常處理
SETSERVEROUTPUTON
DECLARE
vempnoNUMBER(5):=7788;
emp_recemp%ROWTYPE;
BEGIN
SELECT*INTOemprecFROMempWHERE
empno=vempno;
DELETEFROMempWHEREempno=vempno;
第7章游標(biāo)和異常處理
INSERTINTOemplVALUESemp_rec;
IFSQL%FOUNDTHEN
COMMIT;
DBMS_OUTPUT.PUT_LINE(,雇員復(fù)制成功!
');
ELSE
ROLLBACK;
DBMS_OUTPUT.PUT_LINE(,雇員復(fù)制失敗!
');
ENDIF;
END;
第7章游標(biāo)和異常處理
執(zhí)行結(jié)果為:
雇員復(fù)制成功!
PL/SQL過程已成功完成。
步驟2:顯示復(fù)制結(jié)果:
SELECTempno,ename,jobFROMempl;
執(zhí)行結(jié)果為:
EMPNOENAMEJOB
7788SCOTTANALYST
第7章游標(biāo)和異常處理
說(shuō)明:empjrec變量是根據(jù)emp表定義的記錄變量,
SELECT…INTO…語(yǔ)句將整個(gè)記錄傳給該變量。INSERT
語(yǔ)句將整個(gè)記錄變量插入empl表,如果插入成功
(SQL%FOUND為真),則提交事務(wù),否則回滾撤銷事務(wù)。
試修改雇員編號(hào)為7902,重新執(zhí)行以上程序。
第7章游標(biāo)和異常處理
【訓(xùn)練2】輸出雇員工資,雇員工資用不同高度
的*表示。
輸入并執(zhí)行以下程序:
SETSERVEROUTPUTON
BEGIN
FORreIN(SELECTename,salFROMEMP)LOOP
DBMS_OUTPUT.PUT_LINE(rpad(re.ename,12;
')||rpad('*'je.sal/100,'*'));
ENDLOOP;
END;
第7章游標(biāo)和異常處理
輸出結(jié)果為:
7,
SMITH*T*
KX>
ALLEN*T*
WARD^jxvj^K!^
JONES7,^1,-1,7,7,w?x^^1,7,7,w?x^^f,d1,7,7,^f,^f.
MARTINKI^vf^KIXKI^
BLAKEKix、1,^1,%T^d[,^f,7,^1,
CLARKv!^vj>7,^1,7,7,^1,7,7,^1,KI^K!^
SCOTT^f?7,^1,-1,7,7,w?x^^1,7,7,w?x^^1,—1,7,7,^f,^f.
第7章游標(biāo)和異常處理
KING
7,%x^7,7,yj^^fxKI^KI^vf^%J>?J^
7,^1,%j^
^T*^r*
7,7,7.^1,7,7?^1,^i>
TURNER<Tw*TM<T**TW*TW
7,7.^1,^j>\f<*
ADAMS^T*^r*^T*
JAMESvf^KJ^
7,^f,7.^1,7,7?^1,^i>.f<*7,7.^1,^f>.f<*7,7^^1,
FORD<Tw*TM<T**TW*T*<Tw
MILLERyf^yj^KI^%I>KJ^v!>
執(zhí)行結(jié)果為:
PL/SQL過程已成功完成。
說(shuō)明:第一個(gè)rpad函數(shù)產(chǎn)生對(duì)齊效果,第二個(gè)rpad函數(shù)
根據(jù)工資額產(chǎn)生不同數(shù)目的*。該程序采用了隱式的簡(jiǎn)略游
標(biāo)循環(huán)形式°
出dL「一
第7章游標(biāo)和異常處理
【訓(xùn)練3】編寫程序,格式化輸出部門信息。
輸入并執(zhí)行如下程序:
SETSERVEROUTPUTON
DECLARE
vcountnumber:=0;
CURSORd印tcursorISSELECT*FROMdept;
BEGIN
DBMSOUTPUT.PUTLINEC部門列表,);
第7章游標(biāo)和異常處理
DBMS_OUTPUT.PUT_LINE(!--------------------------
-——');
FORDeptrecordINdeptcursorLOOP
DBMS_OUTPUT.PUT_LINE(1部門編號(hào):f||
Deptrecord.deptno);
DBMS_OUTPUT.PUT_LINE(1部門名稱:f||
Deptrecord.dname);
DBMS_OUTPUT.PUT_LINE(,所在城市:]
Deptrecord.loc);
第7章游標(biāo)和異常處理
DBMSOUTPUT.PUTLINEC1------
-——');
v_count:=v_count+1;
ENDLOOP;
DBMSOUTPUT.PUTLINEC共有
[|to_char(v_count)『個(gè)部門!,);
END;
第7章游標(biāo)和異常處理
輸出結(jié)果為:
部門列表
部門編號(hào):10
部門名稱:ACCOUNTING
所在城市:NEWYORK
第7章游標(biāo)和異常處理
部門編號(hào):20
部門名稱:RESEARCH
所在城市:DALLAS
???
共有4個(gè)部門!
PL/SQL過程已成功完成。
說(shuō)明:該程序中將字段內(nèi)容垂直排列。V_count變
量記錄循環(huán)次數(shù),即部門個(gè)數(shù)。
^4
第7章游標(biāo)和異常處理
【訓(xùn)練4】已知每個(gè)部門有一個(gè)經(jīng)理,編寫程序,
統(tǒng)計(jì)輸出部門名稱、部門總?cè)藬?shù)、總工資和部門經(jīng)理。
輸入并執(zhí)行如下程序:
SETSERVEROUTPUTON
DECLARE
vdeptnonumber(8);
vcountnumber(3);
vsumsalnumber(6);
vdnamevarchar2(15);
第7章游標(biāo)和異常處理
vmanagervarchar2(15);
CURSORlistcursorIS
SELECTdeptno,count(*),sum(sal)FROMemp
groupbydeptno;
BEGIN
OPENlistcursor;
DBMS_OUTPUT.PUT_LINE(f----------部門統(tǒng)計(jì)
表--------,);
第7章游標(biāo)和異常處理
DBMS_OUTPUT.PUT_LINE(,部門名稱總?cè)藬?shù)總
工資部門經(jīng)理);
FETCHlistcursorINTOv_deptno,v_count,v_sumsal;
WHILElist_cursor%foundLOOP
SELECTdnameINTOvdnameFROMdept
WHEREdeptno=vdeptno;
SELECTenameINTOvmanagerFROMemp
WHEREdeptno=v_deptnoandjob='MANAGER';
第7章游標(biāo)和異常處理
DBMS_OUTPUT.PUT_LINE(rpad(v_dname,13)||rpad(to_
char(v_count),8)
||rpad(to_char(v_sumsal),9)11vmanager);
FETCHlistcursorINTOv_deptno,v_count,v_sumsal;
ENDLOOP;
DBMSOUTPUT.PUTLINEC1---------------------------
-----------,);
CLOSElistcursor;
END;
第7章游標(biāo)和異常處理
輸出結(jié)果為:
-------------部門統(tǒng)計(jì)表------------
部門名稱總?cè)藬?shù)總工資部門經(jīng)理
ACCOUNTING38750CLARK
RESEARC
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度股東保密協(xié)議及企業(yè)風(fēng)險(xiǎn)管理合同
- 2025年度綠色建筑環(huán)保施工合同規(guī)范范本
- 漯河2024年河南漯河市臨潁縣事業(yè)單位招聘30人筆試歷年參考題庫(kù)附帶答案詳解
- 瀘州四川瀘州瀘縣氣象局見習(xí)基地招收見習(xí)人員2人筆試歷年參考題庫(kù)附帶答案詳解
- 江西2025年江西應(yīng)用工程職業(yè)學(xué)院招聘7人筆試歷年參考題庫(kù)附帶答案詳解
- 杭州浙江杭州西湖區(qū)住房和城鄉(xiāng)建設(shè)局招聘編外合同制工作人員筆試歷年參考題庫(kù)附帶答案詳解
- 2025年中國(guó)塑料保潔車市場(chǎng)調(diào)查研究報(bào)告
- 2025年中國(guó)兒童塑料椅市場(chǎng)調(diào)查研究報(bào)告
- 2025至2031年中國(guó)雨敵行業(yè)投資前景及策略咨詢研究報(bào)告
- 2025至2031年中國(guó)通PLUS1軟件行業(yè)投資前景及策略咨詢研究報(bào)告
- 第三屆全國(guó)石油工程設(shè)計(jì)大賽作品(油藏工程設(shè)計(jì)單項(xiàng))
- 壓力性損傷護(hù)理質(zhì)控細(xì)則及集束化管理措施
- 《批判性思維原理和方法》全套教學(xué)課件
- 高校輔導(dǎo)員招聘筆試試題及答案
- 產(chǎn)后康復(fù)-腹直肌分離
- 丙烯-危險(xiǎn)化學(xué)品安全周知卡
- 2024-2030年中國(guó)免疫檢查點(diǎn)抑制劑行業(yè)市場(chǎng)研究分析及投資機(jī)會(huì)預(yù)測(cè)報(bào)告
- 《太常引·建康中秋夜為呂叔潛賦》示范課教學(xué)設(shè)計(jì)(部編人教版九年級(jí)語(yǔ)文下冊(cè))
- 《配電網(wǎng)設(shè)施可靠性評(píng)價(jià)指標(biāo)導(dǎo)則》
- 2024年國(guó)家電網(wǎng)招聘之通信類題庫(kù)附參考答案(考試直接用)
- 浙教版一年級(jí)下冊(cè)勞動(dòng)全冊(cè)教學(xué)課件
評(píng)論
0/150
提交評(píng)論