a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 數(shù)據(jù)庫 > Oracle > 正文

oracle cursor and exception

2024-08-29 13:54:52
字體:
來源:轉載
供稿:網友
/*游標是SQL的一個內存工作區(qū),有系統(tǒng)或用戶以變量的形式定義。游標的作用就是用于臨時存儲從數(shù)據(jù)庫中提取的數(shù)據(jù)塊。游標有兩種類型:顯示游標和隱式游標。一次從數(shù)據(jù)庫中提取一行數(shù)據(jù),對于這種形式的查詢和DML操作,系統(tǒng)都會使用一個隱式游標,如果要提取多行數(shù)據(jù),就要有程序員定義一個顯示游標,并通過與游標有關的語句進行處理。顯示游標對應一個返回結果為多行多列的SELECT語句。游標一旦打開,數(shù)據(jù)就從數(shù)據(jù)庫中傳送到游標變量中,然后應用程序再從游標中分解出需要的數(shù)據(jù),并進行處理。*//**隱式游標DML操作和單行SELECT語句使用隱式游標INSERT, UPDATE,  DELETE,  SELECT...INTO...當系統(tǒng)使用一個隱式游標時,可以通過隱式游標的屬性來了解操作的狀態(tài)和結果,進而控制程序的流程。隱式游標可以使用名字SQL來訪問,但要注意,通過SQL游標名總是只能訪問前一個DML操作或單行SELECT操作的游標屬性。所以通常在剛剛執(zhí)行完操作之后哦,立即使用SQL游標名來訪問屬性。游標的屬性有以下四種:隱式游標的屬性          返回值類型      意 義SQL%ROWCOUNT           整型             代表DML 語句成功執(zhí)行的數(shù)據(jù)行數(shù)SQL%FOUND              布爾型            值為TRUE 代表插入、刪除、更新或單行查詢操作成功SQL%NOTFOUND           布爾型            與SQL%FOUND 屬性返回值相反SQL%ISOPEN             布爾型            DML 執(zhí)行過程中為真,結束后為假*/--使用隱式游標的屬性,判斷對雇員工資的修改是否成功declarebegin  update scott.emp emp set emp.sal = sal+100  where empno=7788;  if SQL%FOUND then    dbms_output.put_line('OK');     commit;  else      dbms_output.put_line('fail');   end if;end;      --使用隱式游標的屬性,判斷修改員工的行數(shù)declarebegin     update scott.emp emp set emp.sal = sal+1;       dbms_output.put_line(SQL%ROWCOUNT);    end;     --輸出結果:20/**顯示游標顯示游標的使用分為以下4個步驟1. 聲明游標  在DECLARE部分按以下格式聲明游標:  CURSOR 游標名[(參數(shù)1 數(shù)據(jù)類型[,參數(shù)2 數(shù)據(jù)類型...])]  IS SELECT語句:  參數(shù)是可選部分,所定義的參數(shù)可以出現(xiàn)在SELECT語句的WHERE子句中。如果定義了參數(shù),則必須在打開游標時傳遞相應的實際參數(shù)  SELECT語句是對表或視圖的查詢語句,甚至也可以是聯(lián)合查詢,可以帶WHERE條件、ORDER BY或GROUP BY等子句,但不能使用INTO子句。在SELECT語句中可以使用在定義游標之前定義的變量2. 打開游標  在可執(zhí)行部分,按以下格式打開游標  OPEN 游標名[(實際參數(shù)1[,實際參數(shù)2...])]  打開游標時,SELECT語句的查詢結果就被傳遞到了游標工作區(qū)。3. 提取數(shù)據(jù)  在可執(zhí)行部分,按以下格式將游標工作區(qū)中的數(shù)據(jù)提取到變量中。提取操作必須在打開游標之后進行。  FETCH 游標名 INTO 變量名1,變量2...]  或  FETCH 游標名 INTO 記錄變量;  游標打開后有一個指針指向數(shù)據(jù)區(qū),F(xiàn)ETCH語句一次返回指針值得一行數(shù)據(jù),要返回多行重復執(zhí)行,可以使用循環(huán)語句來實現(xiàn)??刂蒲h(huán)可以通過判斷游標的屬性來進行。下面對這兩種格式進行說明: 1).變量名是用來從游標中提取數(shù)據(jù)的變量,需要事先定義。變量的個數(shù)和類型應該與SELECT語句中的字段變量的個數(shù)和類型一致 2).一次將一行數(shù)據(jù)提取到記錄變量中,需要使用%ROWTYPE事先定義記錄變量,這種形式使用起來比較方便,不必分別定義和使用 多個變量     定義記錄變量的方法如下:     變量名 表名|游標名%ROWTYPE;     其中的表必須存在,游標名也必須先定義      4. 關閉游標  CLOSE 游標名  顯示游標名打開后,必須顯示地關閉。游標一旦關閉,游標占用的資源就被釋放,游標變成無效,必須重新打開才能使用。*/      --用游標提取emp表中7788雇員的名稱和職務declare v_ename varchar(10); v_job varchar(10); cursor emp_cursor IS select emp.ename, emp.job from scott.emp emp; begin   open emp_cursor;   fetch emp_cursor into v_ename, v_job;   DBMS_OUTPUT.PUT_LINE(v_ename||','||v_job);    close emp_cursor;   end; --執(zhí)行結果:SCOTT,ANALYST   --用游標變量提取emp中7788雇員的名稱和職務  declare    cursor emp_cursor is    select emp.ename, emp.job from scott.emp emp where emp.empno=7788;    emp_record emp_cursor%ROWTYPE;    begin      open emp_cursor;      fetch emp_cursor into emp_record;      DBMS_OUTPUT.PUT_LINE(emp_record.ename||','||emp_record.job);      close emp_cursor;      end; --執(zhí)行結果:SCOTT,ANALYST           --顯示工資最高的前三名雇員的名稱和工資。DECLARE v_ename varchar(10); v_sal number(5); cursor emp_cursor is select emp.ename, emp.sal from scott.emp emp where sal>0 order by sal desc ; begin   open emp_cursor;   for i in 1..3 loop     fetch emp_cursor into v_ename, v_sal;      DBMS_OUTPUT.PUT_LINE(v_ename||','||v_sal);   end loop;        close emp_cursor; end;           /*輸出結果KING,5000SCOTT,3100FORD,3000*//* 游標循環(huán) 1*/--顯示全部雇員的編號和名稱。DECLARE  CURSOR emp_cursor is select empno, ename from scott.emp; begin   for emp_record in emp_cursor loop     DBMS_OUTPUT.PUT_LINE(emp_record.empno||emp_record.ename);     end loop; end;/* 游標循環(huán) 2 省略游標的定義,游標的SELECT查詢語句在循環(huán)中直接出現(xiàn)*/declarebegin  for re in(select emp.ename from scott.emp emp) loop    DBMS_OUTPUT.PUT_LINE(re.ename);  end loop;end;/*顯示游標屬性雖然可以使用前面的形式獲得游標數(shù)據(jù),但是在游標定義以后使用它的一些屬性結構控制是一種更為靈活的方法。顯示游標的屬性如表:游標的屬性    返回值類型        意 義%ROWCOUNT      整型             獲得FETCH 語句返回的數(shù)據(jù)行數(shù)%FOUND         布爾型           最近的FETCH 語句返回一行數(shù)據(jù)則為真,否則為假%NOTFOUND      布爾型           與%FOUND 屬性返回值相反%ISOPEN        布爾型           游標已經打開時值為真,否則為假可按照以下形式取得游標的屬性游標名%屬性要判斷游標emp_cursor是否處于打開狀態(tài),可以使用屬性emp_cursor%ISOPEN。如果游標已經打開,則返回值為"真",否則為"假"*/declarev_ename varchar2(10);cursor emp_cursor isselect emp.ename from scott.emp emp;begin  open emp_cursor;  if emp_cursor%ISOPEN then    loop      fetch emp_cursor into v_ename;      exit when emp_cursor%NOTFOUND;      DBMS_OUTPUT.PUT_LINE(to_char(emp_cursor%ROWCOUNT)||'-'||v_ename);    end loop;  else    DBMS_OUTPUT.PUT_LINE('用戶信息:游標沒有打開!');  end if;   close emp_cursor;  end;--帶參數(shù)的游標 打開游標的時候的參數(shù)declarev_empno number(5);v_ename varchar2(10);cursor emp_cursor(p_deptno number, p_job varchar2) is select empno, ename from scott.emp emp where emp.deptno=p_deptno and emp.job=p_job; begin   open emp_cursor(10, 'CLERK');   if emp_cursor%ISOPEN then     loop       fetch emp_cursor into v_empno, v_ename;       dbms_output.put_line(v_empno||'-'|| v_ename);       exit when emp_cursor%NOTFOUND;     end loop;   else     DBMS_OUTPUT.PUT_LINE('用戶信息:游標沒有打開!');   end if; end;  --帶參數(shù)的游標 通過變量向游標傳遞參數(shù),變量需要先于游標定義,并在游標打開之前賦值 declare  v_empno number(5);  v_ename varchar(10);  v_depno number(5);  v_job varchar2(10);  cursor emp_cursor IS   select emp.empno, emp.ename from scott.emp emp where emp.deptno=v_depno and emp.job=v_job;   begin     v_depno:=10;     v_job:='CLERK';     open emp_cursor;     loop        fetch emp_cursor into v_empno, v_ename;       exit when emp_cursor%NOTFOUND;       DBMS_OUTPUT.PUT_LINE(v_empno||','||v_ename);     end loop;   end; --輸出結果:7934,MILLER/* 動態(tài)SELECT語句和動態(tài)游標的用法  對于查詢結果為一行的select語句,可以用動態(tài)生成查詢語句字符串的方法,在程序執(zhí)行階段臨時生成并執(zhí)行, execute immediate 查詢語句字符串 into 變量1、、*/declarestr varchar2(100);v_ename varchar2(10);begin  str := 'select emp.ename from scott.emp emp where emp.empno=7788';  execute immediate str into v_ename;  dbms_output.put_line(v_ename);  end;/*定義游標類型的語句如下:TYPE 游標類型名 REF CURSOR聲明游標變量的語句如下:在可執(zhí)行部分可以如下形式打開一個動態(tài)游標open 游標變量名 for 查詢語句字符串;*/--按名字中包含的字母順序分組顯示雇員信息declaretype cur_type is ref cursor;cur cur_type;--聲明為一個未綁定的游標rec scott.emp%rowtype;str varchar2(550);letter char :='A';begin  loop    str:='select emp.ename from scott.emp where emp.ename like ''%'||letter||'%''';    open cur for str;    dbms_output.put_line('包含字母'||letter||'的名字:');    loop      fetch cur into rec.ename;      exit when cur%notfound;      dbms_output.put_line(rec.ename);    end loop;    exit when letter='Z';    letter:=chr(ascii(letter)+1);    end loop; end;        /* 異常處理  錯誤是在標準包中由系統(tǒng)預定義的標準錯誤,或是有用戶在程序的說明部分自定義的錯誤。  */  --查詢編號為1234的雇員名字 declare v_name varchar2(10); begin   select emp.ename into v_name from scott.emp emp where emp.empno=1234;   DBMS_OUTPUT.PUT_LINE('該雇員名字為:'|| v_name);   EXCEPTION     WHEN NO_DATA_FOUND THEN       DBMS_OUTPUT.PUT_LINE('無改用戶');      WHEN OTHERS THEN        DBMS_OUTPUT.PUT_LINE('其他錯誤'); end; --執(zhí)行結果:無改用戶  --由程序代碼顯示系統(tǒng)錯誤  DECLARE  V_TEMP NUMBER(5):=1;  BEGIN    V_TEMP:=V_TEMP/0;    EXCEPTION      WHEN OTHERS THEN        DBMS_OUTPUT.PUT_LINE('發(fā)生系統(tǒng)錯誤!');         DBMS_OUTPUT.PUT_LINE('錯誤代碼:'|| SQLCODE( ));  DBMS_OUTPUT.PUT_LINE('錯誤信息:' ||SQLERRM( ));END;/*錯 誤 名 稱                      錯誤代碼       錯 誤 含 義CURSOR_ALREADY_OPEN          ORA_06511        試圖打開已經打開的游標INVALID_CURSOR               ORA_01001        試圖使用沒有打開的游標DUP_VAL_ON_INDEX             ORA_00001        保存重復值到惟一索引約束的列中ZERO_DIVIDE                  ORA_01476        發(fā)生除數(shù)為零的除法錯誤INVALID_NUMBER               ORA_01722        試圖對無效字符進行數(shù)值轉換ROWTYPE_MISMATCH             ORA_06504        主變量和游標的類型不兼容VALUE_ERROR                  ORA_06502        轉換、截斷或算術運算發(fā)生錯誤TOO_MANY_ROWS                ORA_01422        SELECT…INTO…語句返回多于一行的數(shù)據(jù)NO_DATA_FOUND                ORA_01403        SELECT…INTO…語句沒有數(shù)據(jù)返回TIMEOUT_ON_RESOURCE          ORA_00051        等待資源時發(fā)生超時錯誤TRANSACTION_BACKED_OUT       ORA_00060        由于死鎖,提交失敗STORAGE_ERROR                ORA_06500        發(fā)生內存錯誤PROGRAM_ERROR                ORA_06501        發(fā)生PL/SQL 內部錯誤NOT_LOGGED_ON                ORA_01012        試圖操作未連接的數(shù)據(jù)庫LOGIN_DENIED                 ORA_01017        在連接時提供了無效用戶名或口令www.*/--定義新的系統(tǒng)錯誤類型。DECLAREV_ENAME VARCHAR2(10);NULL_INSERT_ERROR EXCEPTION;PRAGMA EXCEPTION_INIT(NULL_INSERT_ERROR,-1400);BEGININSERT INTO EMP(EMPNO) VALUES(NULL);EXCEPTIONWHEN NULL_INSERT_ERROR THENDBMS_OUTPUT.PUT_LINE('無法插入NULL值!');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('發(fā)生其他系統(tǒng)錯誤!');END;--執(zhí)行結果為:無法插入NULL值!
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 免费av在线网 | 成人免费高清 | 91蜜桃视频 | 亚洲国产精品t66y | 天天干天天操天天爽 | 色黄视频在线看 | 日韩av在线免费电影 | 色综合国产 | 精品国模一区二区三区欧美 | 国产麻豆乱码精品一区二区三区 | 久久精品国产免费 | 伊人网站| 日韩在线二区 | 欧美激情视频一区二区三区在线播放 | 精品日韩一区二区三区免费视频 | 久草在线在线精品观看 | 亚洲视频自拍 | 四虎入口 | 国产在线一区二区三区 | 国产精品二区一区二区aⅴ污介绍 | 日韩视频二区 | 嫩呦国产一区二区三区av | 91久久精品 | 日本a在线播放 | 国产日韩亚洲欧美 | 欧美电影一区 | 中文字幕在线精品 | 成人在线免费观看 | 日韩黄色在线 | 成人免费小视频 | 超黄视频在线观看 | 国产精品中文字幕在线播放 | 久久亚洲国产精品日日av夜夜 | 日日操视频| 黄色在线网站 | 国产伦精品一区二区三区不卡视频 | 亚洲 欧美 综合 | 国产精品久久av | 免费www xxx| 色爱区综合五月激情 | 日本黄色影片在线观看 |