數(shù)據(jù)庫講義2游標異常(課堂版)_第1頁
數(shù)據(jù)庫講義2游標異常(課堂版)_第2頁
數(shù)據(jù)庫講義2游標異常(課堂版)_第3頁
數(shù)據(jù)庫講義2游標異常(課堂版)_第4頁
數(shù)據(jù)庫講義2游標異常(課堂版)_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、1.游標游標提供了一種從表中檢索數(shù)據(jù)并進行操作的靈活手段。PL/SQL在執(zhí)行SELECT、INSERT、DELETE和UPDATE語句時,ORACLE會在內(nèi)存中為其分配上下文區(qū)(Context Area),即緩沖區(qū)。游標是指向該區(qū)的一個指針,通過游標PL/SQL程序可以一次處理查詢結(jié)果集中的一行,并可以對該行數(shù)據(jù)執(zhí)行特定操作,從而為用戶在處理數(shù)據(jù)的過程中提供方便。在oracle中,主要使用顯式游標,隱式游標,動態(tài)游標(以后講存儲過程實現(xiàn)分頁的時候)。2. 顯式(示)游標顯式游標是由用戶聲明和操作的一種游標,通常用于操作查詢結(jié)果集(即由select語句返回的查詢結(jié)果),使用它處理數(shù)據(jù)的步驟為:聲

2、明游標、打開游標、讀取游標和關(guān)閉游標4個步驟。其中,讀取游標很可能是一個反復的步驟(迭代),因為游標每次只能讀取一行數(shù)據(jù),對于多條記錄,需要反復讀取,直到游標讀取不到數(shù)據(jù)為止。2-1 游標使用的步驟a. 聲明游標定義游標名字,以及對應的select語句。 CURSOR cursor_name(input_parameter1, input_parameter2) RETURN ret_type IS select_statement;cursor_name: 所聲明游標名稱ret_name: 執(zhí)行游標操作后的返回值類型,這是一個可選項。select_statement: 游標所使用的selec

3、t語句,為游標的反復讀取提供了結(jié)果集。input_parameter1: 游標的“輸入?yún)?shù)”,可以有多個,這是可選項。它指定用戶在打開游標后,向游標中傳遞的值,該參數(shù)的定義和初始化格式如下: para_name in datatype := | default para_value 其中,para_name表示參數(shù)名稱,其后面的關(guān)鍵字"in"表示輸入方向,可以省略;datatype表示參數(shù)的數(shù)據(jù)類型,但數(shù)據(jù)不可以指定長度; para_value表示該參數(shù)的初始值或默認值,也可以是表達式; para_name參數(shù)的初始值可以用常規(guī)方式賦值(:=),也可以使用關(guān)鍵字defaul

4、t。示例代碼:聲明一個游標,用來讀取emp表中職務是銷售員(SALESMEN)的雇員信息。declare cursor cur_emp(var_job in varchar2:='SALESMEN') is select empno, ename, sal from emp where job=var_job;b. 打開游標在游標聲明完畢之后,必須打開才能使用,打開游標的語法:open cur_name(para_values1,para_values2.);cur_name: 打開游標的名字para_values1: 指定“輸入?yún)?shù)”的值,根據(jù)聲明游標時的實際情況,可以是多個

5、或一個,這是可選項。示例代碼:open cur_emp('MANAGER');c. 讀取游標fetch cur_name into variable;variable: 表明一個變量列表或者“記錄”變量(RECORD類型),oracle使用“記錄”變量來存儲游標中的數(shù)據(jù)。在游標中包含了一個數(shù)據(jù)行指針,其用來指向當前數(shù)據(jù)行。剛剛打開游標時,指針指向結(jié)果集中的第一行,當使用fetch-into語句讀取數(shù)據(jù)完畢后,游標中的指針自動指向下一行數(shù)據(jù),直到指針指向結(jié)果集中最后一條記錄之后為止(當最后一條記錄為空時,表示讀取完畢),這是游標的%found屬性值為false.4. 關(guān)閉游標游標

6、使用完畢后,需要關(guān)閉,以釋放資源。close cur_name;整個游標操作的示例代碼:declare cursor cur_emp (var_job varchar2 := 'SALESMAN') is select empno, ename, sal from emp where job = var_job; type record_emp is record (var_empno emp.empno%type, var_ename emp.ename%type, var_sal emp.sal%type); emp_row record_emp;begin open cu

7、r_emp('MANAGER'); fetch cur_emp into emp_row; while cur_emp%found loop dbms_output.put_line(emp_row.var_ename|'的編號'|emp_row.var_empno|',的工資'|emp_row.var_sal); fetch cur_emp into emp_row; end loop; close cur_emp;end;/2-2 游標的屬性游標有4個屬性:%found: 布爾型屬性,如果SQL語句至少影響到一行的數(shù)據(jù),該屬性為true, 否

8、則為false%notfound:布爾型屬性,與%found相反。%isopen: 布爾型屬性,游標是否打開%rowcount: 數(shù)字型屬性,返回受SQL語句影響的行數(shù)使用指南,聲明一個游標,檢索指定員工編號的雇員信息,然后使用游標的%found屬性來判斷是否檢索到指定員工編號的雇員信息。declare var_name varchar2(50); var_job varchar2(50); /*聲明游標*/ cursor cur_emp is select ename, job form emp where empno=7499;begin open cur_emp; fetch cur_e

9、mp into var_name, var_job; if cur_emp%found then dbms_output.put_line('編號是7499'|var_name); else dbms_output.put_line('查無此人'); endif;end;/3. 隱式游標在執(zhí)行一個SQL語句時,oracle會自動創(chuàng)建一個隱式游標。這個游標是內(nèi)存中處理該語句的工作區(qū)域。隱式游標主要處理數(shù)據(jù)操縱語句(如update, delete語句)的執(zhí)行結(jié)果,當然,特殊情況下,也可以處理select語句的查詢結(jié)果。隱式游標,也有屬性。當使用隱式游標的屬性時,需要

10、在屬性前面加上隱式游標的默認名稱-SQL.示例代碼:把emp表中銷售員(SALESMAN)的工資上調(diào)20%,使用隱式游標的屬性輸出上調(diào)工資的員工數(shù)量。begin update emp set sal=sal*(1+0.2) where job='SALESMAN' if sql%notfound then dbms_output.put_line('沒有雇員上調(diào)工資'); else dbms_output.put_line('有'|sql%rowcount|'個雇員上調(diào)工資'); end if;end;/4. 通過for語句循環(huán)遍

11、歷游標使用for語句遍歷游標中的數(shù)據(jù)時,可以把其計數(shù)器看做一個自動的RECORD類型變量。4-1 遍歷顯式游標for var_auto_record in cur_name loop plsqlsentence;end loop; var_auto_record: 自動的RECORD類型的變量,可以是任意合法的變量名稱。 cur_name: 指定游標的名稱 plsqlsentence: PL/SQL語句示例代碼:使用顯示游標和for語句檢索部門編號是30的雇員信息并輸出:declare cursor cur_emp is select * from emp where deptno=30;be

12、gin for emp_record in cur_emp loop dbms_output.put(emp_record.empno); dbms_output.put(emp_record.ename); dbms_output.put(emp_record.job); end loop;end;4-2 使用隱式游標和for語句begin for emp_record in (select empno, ename, sal from emp where job='SALESMAN') loop dbms_output.put(emp_record.empno); dbms

13、_output.put(emp_record.ename); dbms_output.put_line(emp_record.sal); end loop;end;/ 5. 異常理解成java trycatch-.在PL/SQL程序中,有exception塊的定義。declarebeginexceptionend;/在編寫PL/SQL程序時,避免不了發(fā)生一些錯誤,可能是程序員自己造成,也可能是操作系統(tǒng)或者硬件環(huán)境錯誤,比如除數(shù)為零,磁盤I/O錯誤等,oracle采用異常機制來處理,異常處理代碼通常放在PL/SQL的exception代碼塊中。根據(jù)異常產(chǎn)生的機制和原理,oracle異常分為兩大類

14、: 預定義異常:oracle系統(tǒng)自身為用戶提供大量的、可在PL/SQL中使用的預定義異常,以便檢查用戶代碼失敗的一般原因。這種異常,用戶無序搭理,由oracle自動引發(fā)。 自定義異常:出現(xiàn)操作系統(tǒng)錯誤,機器硬件損壞等,以及業(yè)務實際需求,程序設(shè)計人員需要自定義一些錯誤的業(yè)務邏輯,而PL/SQL程序在運行過程中,可能觸發(fā)這些錯誤的業(yè)務邏輯,對于上述異常,需要在程序中自定義異常,然后由oracle自動觸發(fā)。 5-1 預定義異常 當PL/SQL程序返回了oracle系統(tǒng)內(nèi)部規(guī)定的設(shè)計規(guī)范,會自動引發(fā)一個預定義異常,詳見表格: 預定義說明的部分 ORACLE 異常錯誤錯誤號異常錯誤信息名稱說明ORA-0

15、001Dup_val_on_index違反了唯一性限制ORA-0051Timeout-on-resource在等待資源時發(fā)生超時ORA-0061Transaction-backed-out由于發(fā)生死鎖事務被撤消ORA-1001Invalid-CURSOR試圖使用一個無效的游標ORA-1012Not-logged-on沒有連接到ORACLEORA-1017Login-denied無效的用戶名/口令ORA-1403No_data_foundSELECT INTO沒有找到數(shù)據(jù)ORA-1422Too_many_rowsSELECT INTO 返回多行ORA-1476Zero-divide試圖被零除OR

16、A-1722Invalid-NUMBER轉(zhuǎn)換一個數(shù)字失敗ORA-6500Storage-error內(nèi)存不夠引發(fā)的內(nèi)部錯誤ORA-6501Program-error內(nèi)部錯誤ORA-6502Value-error轉(zhuǎn)換或截斷錯誤ORA-6504Rowtype-mismatch宿主游標變量與 PL/SQL變量有不兼容行類型ORA-6511CURSOR-already-OPEN試圖打開一個已處于打開狀態(tài)的游標ORA-6530Access-INTO-null試圖為null 對象的屬性賦值ORA-6531Collection-is-null試圖將Exists 以外的集合( collection)方法應用于一

17、個null pl/sql 表上或varray上ORA-6532Subscript-outside-limit對嵌套或varray索引得引用超出聲明范圍以外ORA-6533Subscript-beyond-count對嵌套或varray 索引得引用大于集合中元素的個數(shù).示例代碼:使用select into語句檢索emp表中部門編號為10的雇員記錄信息,然后使用too_many_rows預定義異常捕獲錯誤信息并輸出,代碼如下:declare var_empno number; var_ename varchar2(50);begin select empno, ename into var_emp

18、no, var_ename from emp where deptno=10; if sql%found then dbms_output.put_line(var_empno|' '|var_ename); end if;exception when too_many_rows then dbms_output.put_line("返回記錄超過一行"); when no_data_found then dbms_output.put_line("無數(shù)據(jù)記錄"); -處理所有的錯誤 when others then dbms_output

19、.put_line(SQLCODE|'-'|SQLERRM);end;/注意:oracle系統(tǒng)內(nèi)部規(guī)定不允許select into語句的返回行數(shù)超過一行,所以,必然會引發(fā)異常,即引發(fā)too_many_rows系統(tǒng)預定義異常。5-2 自定義異常oracle系統(tǒng)內(nèi)部的預定義異常僅僅20多個,而實際程序運行過程中可能產(chǎn)生幾千個異常情況,為此oracle經(jīng)常使用錯誤編號和相關(guān)描述輸出異常。另外,程序員可以根據(jù)實際的業(yè)務需求定義一些特殊的異常,這樣oracle的自定義異常分為:錯誤編號異常和業(yè)務邏輯異常兩種。5-2-1 錯誤編號異常錯誤編號異常指的是:oracle系統(tǒng)發(fā)生錯誤時,系統(tǒng)會顯

20、示錯誤編號和相關(guān)的異常信息。對于這種異常,首先在聲明部分使用exception類型定義一個異常變量名,然后使用語句pragme exception_init為“錯誤編號”關(guān)聯(lián)這個異常變量名,接下來可以像對待系統(tǒng)預定義異常一樣來處理。實際演示:向dept表中插入一個部門編號為10的記錄(事先已知,10已經(jīng)存在,并且dept為唯一主鍵),執(zhí)行insert操作,會顯示-0001的錯誤編號。定義錯誤編號為"-00001"的異常變量,然后向dept表中插入一條“違反唯一約束條件”的記錄,最后在exception代碼塊輸出異常提示信息。declare v_exception_key e

21、xception; -定義一個異常變量 pragma exception_init(v_exception_key,-00001); -關(guān)聯(lián)錯誤號和異常變量名begin insert into dept values(1,'',''); exception when v_exception_key then dbms_output.put_line('違反主鍵約束'); - when NO_DATA_FOUND then - dbms_output.put_line('沒有數(shù)據(jù)'); -處理所有的錯誤 when others then dbms_output.put_line(SQLCODE|'-'|SQLERRM); end;5-2-2 業(yè)務邏輯異常符合數(shù)據(jù)庫的規(guī)范,但是,不符合現(xiàn)實邏輯。 在實際的應用中,程序開放人員可以根據(jù)具體的業(yè)務邏輯規(guī)則自定義一個異常。這樣,當用戶違反業(yè)務邏輯規(guī)則時,引發(fā)一個自定

溫馨提示

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

評論

0/150

提交評論