oracle 對象管理 08_遊標與記錄

1、遊標定義
1.遊標是查詢結果集的平面化展現,經過遊標方便定位到結果集中某個特定的行。
2.遊標的分類
    顯示遊標:即用戶自定義遊標,專門用於處理select語句返回的多行數據
    隱式遊標:系統自動定義的遊標,記錄集只有單行數據,用於處理select into 和DML語句
3.遊標使用的通常過程:
    顯示遊標:聲明, 打開, 讀取, 關閉
    隱式遊標:直接使用讀取,聲明、打開、關閉都是系統自動進行的
4顯示遊標的過程描述
a.聲明遊標
    CURSOR cursor_name IS select_statement
    如:CURSOR emp_cur IS SELECT empno,ename,job,sal FROM scott.emp;
b.打開遊標,打開遊標則執行對應的select語句,將對應的結果集存放到遊標當中
    OPEN cursor_name     
c.獲取數據,提取單行數據,須要配合循環語句來使用,提取多行數據,collect爲集合變量
    FETCH cursor_name INTO var_name1,...var_name2 ;   
    FETCH cursor_name BULK COLLECT INTO collect1,collect2,...[LIMIT rows];    
d.關閉遊標
    CLOSE cursor_name 
5.顯示遊標的5個屬性
    cursor_name%ISOPEN         --遊標是否打開   
    cursor_name%FOUND          --最近的FETCH是否提取到數據
    cursor_name%NOTFOUND       --最近的FETCH是否沒有提取到數據
    cursor_name%ROWCOUNT       --返回到目前爲止,已經從遊標緩衝區中提取到數據的行數  
    
2、遊標使用
1.輸入job,輸出ename,sal值
    declare
        v_name emp.ename%type;
        v_sal  emp.sal%type;
        cursor cur_one is select ename,sal from emp where job ='&input';
    begin
        open cur_one;
        dbms_output.put_line('ename          sal');
        loop
            fetch cur_one into v_name,v_sal;
            exit when (cur_one%notfound);
            dbms_output.put_line(v_name||'          '||v_sal);              
        end loop;
        close cur_one;
    end;
2.使用遊標統必定義變量類型
    declare
        cursor cur_one is select ename,sal,job,mgr,hiredate,comm from emp where job ='&input';
        v_cur_col  cur_one%rowtype;
    begin
        open cur_one;
        dbms_output.put_line('ename          sal');
        loop
            fetch cur_one into v_cur_col;
            exit when (cur_one%notfound);
            dbms_output.put_line(v_cur_col.ename||'          '||v_cur_col.sal);              
        end loop;
        close cur_one;
    end;
3.遊標FOR循環
    遊標FOR循環是爲了簡化遊標使用過程而設計的。使用遊標FOR循環檢索遊標時,遊標的打開、數據提取、數據是否檢
索到的判斷與遊標的關閉都是ORACLE系統自動進行的。
    --顯式
    DECLARE
      CURSOR CURSOR_006 IS
        SELECT ENAME, HIREDATE FROM EMP WHERE SAL < &SAL;
    BEGIN
      DBMS_OUTPUT.PUT_LINE('ename      hiredate');
      FOR V_CUR IN CURSOR_006 LOOP
        DBMS_OUTPUT.PUT_LINE(V_CUR.ENAME || '   ' || V_CUR.HIREDATE);
      END LOOP;
    END;
    --隱式
    BEGIN
      DBMS_OUTPUT.PUT_LINE('ename      hiredate');
      FOR V_CUR IN (SELECT ENAME, HIREDATE FROM EMP WHERE SAL < &SAL) LOOP
        DBMS_OUTPUT.PUT_LINE(V_CUR.ENAME || '   ' || V_CUR.HIREDATE);
      END LOOP;
    END;
    
3、記錄
    是一個或多個字段且擁有數據類型的集合體,相似於表的數據結構,定義了PL/SQL記錄類型以後,能夠定義
PL/SQL記錄變量,多用於簡化單行多列的數據處理。
1.記錄的定義
a.自定義記錄成員
    TYPE TYPE_NAME IS RECORD                                      
        (field_name1 datatype1 [NOT NULL] [ := DEFAULT EXPRESSION],
         field_name2 datatype2 [NOT NULL] [ := DEFAULT EXPRESSION],
         ...
         field_nameN datatypeN [NOT NULL] [ := DEFAULT EXPRESSION]);
    record_name TYPE_NAME;
b.參照數據對象定義
    record_name table_name%rowtype
    record_name view_name%rowtype
    reocrd_name cursor_name%rowtype
    
4、記錄的使用
1.使用記錄及記錄成員
    undefine no
    DECLARE
        TYPE emp_record_type IS RECORD
        (
            name emp.ename%TYPE,
            salary emp.sal%TYPE,
            dno emp.deptno%TYPE
        );
        emp_record emp_record_type;
    BEGIN                     
        SELECT ename, sal, deptno INTO emp_record --[select ename,sal into emp_record.name,emp_record.salary]
        FROM emp WHERE empno = &no;
        dbms_output.put_line(emp_record.name);   --輸出時僅僅輸出記錄變量的一個成員emp_record.name
    END;
2.使用PL/SQL記錄(記錄成員)變量
    DECLARE
        dept_record dept%ROWTYPE;
    BEGIN
        dept_record.deptno := 50;
        dept_record.dname := 'ADMINISTRATOR';
        dept_record.loc := 'BEIJING';
        INSERT INTO dept VALUES dept_record;
    END;
3.記錄使用的幾個問題
a.記錄成員非空時必須在定義時給初值
    DECLARE
    TYPE ex_type IS RECORD
        (col1 NUMBER(3),
         col2 VARCHAR2(5) NOT NULL);  --編譯不經過
    ex_record ex_type;
    BEGIN
        ex_record.col1:=15;
        ex_record.col1:=TO_CHAR(ex_record.col1);
        ex_record.col2:='John';
        DBMS_OUTPUT.PUT_LINE('ex_record.col1 is '||ex_record.col1);
        DBMS_OUTPUT.PUT_LINE('ex_record.col2 is '||ex_record.col2);
    END;
    
    DECLARE
      TYPE ex_type IS RECORD(
        col1 NUMBER(3),
        col2 VARCHAR2(5) NOT NULL := 'John');  
      ex_record ex_type;
    BEGIN
      ex_record.col1 := 15;
      ex_record.col1 := TO_CHAR(ex_record.col1);
      ex_record.col2:='TOM';--能夠賦新值
      DBMS_OUTPUT.PUT_LINE('ex_record.col1 is ' || ex_record.col1);
      DBMS_OUTPUT.PUT_LINE('ex_record.col2 is ' || ex_record.col2);
    END;
b.來自不一樣的記錄類型的記錄變量之間不能相互賦值
c.同一個記錄的記錄變量之間能夠相互賦值
d.基於表,遊標,自定義記錄的使用
    DECLARE
      CURSOR dept_cur IS
         SELECT * FROM dept WHERE deptno = 30;
      TYPE dept_type IS RECORD( 
        deptno NUMBER(2),
        dname  VARCHAR2(14),
        loc    VARCHAR2(13));    
      dept_rec1 dept%ROWTYPE;     --聲明基於表dept的記錄變量
      dept_rec2 dept_cur%ROWTYPE; --聲明基於遊標dept_cur的記錄變量
      dept_rec3 dept_type;        --聲明基於自定義dept_type的記錄變量    
    BEGIN
      SELECT * INTO dept_rec1 FROM dept WHERE deptno = 30;    
      OPEN dept_cur;
      LOOP
        FETCH dept_cur
          INTO dept_rec2; 
        EXIT WHEN dept_cur%NOTFOUND;
      END LOOP;    
      dept_rec1 := dept_rec2;
      dept_rec3 := dept_rec2;
    
      DBMS_OUTPUT.PUT_LINE(dept_rec1.deptno || ' ' || dept_rec1.dname);
      DBMS_OUTPUT.PUT_LINE(dept_rec2.deptno || ' ' || dept_rec2.dname);
      DBMS_OUTPUT.PUT_LINE(dept_rec3.deptno || ' ' || dept_rec3.dname);
    END;
 數據結構

相關文章
相關標籤/搜索