[轉載]oracle遊標概念講解

來源:互聯網
上載者:User

標籤:

原文URL:http://www.2cto.com/database/201203/122387.html

ORACLE遊標概念講解
什麼是遊標?  ①從表中檢索出結果集,從中每次指向一條記錄進行互動的機制。      ②關聯式資料庫中的操作是在完整的行集合上執行的。   由SELECT 語句返回的行集合包括滿足該語句的WHERE 子句所列條件的所有行。由該語句返回完整的行集合叫做結果集。      應用程式,尤其是互動和線上應用程式,把完整的結果集作為一個單元處理並不總是有效。      這些應用程式需要一種機制來一次處理一行或連續的幾行。而遊標是對提供這一機制的結果集的擴充。        遊標是通過遊標庫來實現的。遊標庫是常常作為資料庫系統或資料訪問API 的一部分而得以實現的軟體,      用來管理從資料來源返回的資料的屬性(結果集)。這些屬性包括並發管理、在結果集中的位置、返回的行數,      以及是否能夠在結果集中向前和/或向後移動(可滾動性)。        遊標跟蹤結果集中的位置,並允許對結果集逐行執行多個操作,在這個過程中可能返回至原始表,也可能不返回至原始表。      換句話說,遊標從概念上講基於資料庫的表返回結果集。      由於它指示結果集中的當前位置 ,就像電腦螢幕上的游標指示當前位置一樣,“遊標”由此得名。   2,遊標有什麼作用?  ①指定結果集中特定行的位置。  ②基於當前的結果集位置檢索一行或連續的幾行。  ③在結果集的當前位置修改行中的資料。  ④對其他使用者所做的資料更改定義不同的敏感性層級。         ⑤可以以

編程

的方式訪問

資料庫

。      3,為什麼避免使用遊標?  ①在建立遊標時,最需要考慮的事情是,“是否有辦法避免使用遊標?”   因為遊標的效率較差,如果遊標操作的資料超過1萬行,那麼就應該改寫;   如果使用了遊標,就要盡量避免在遊標迴圈中再進行表串連的操作。   4,

Oracle

遊標的類型?  ①靜態資料指標:結果集已經確實(靜態定義)的遊標。分為隱式和顯示遊標。   ⑴隱式遊標:所有DML語句為隱式遊標,通過隱式遊標屬性可以擷取SQL語句資訊。   ⑵顯示遊標:使用者顯示聲明的遊標,即指定結果集。當查詢返回結果超過一行時,就需要一個顯式遊標。  ②REF遊標:動態關連接果集的臨時對象。   5,Oracle遊標的狀態有哪些,怎麼使用遊標屬性?  ①遊標的狀態是通過屬性來表示。   %Found :Fetch語句(擷取記錄)執行情況True or False。   %NotFound : 最後一條記錄是否提取出True or False。   %ISOpen : 遊標是否開啟True or False。   %RowCount :遊標當前提取的行數 。  ②使用遊標的屬性。   例子:/* conn scott/tiger */   Begin    Update emp Set  SAL = SAL + 0.1  Where JOB = ‘CLERK‘;    If  SQL%Found  Then     DBMS_OUTPUT.PUT_LINE(‘已經更新!‘);    Else     DBMS_OUTPUT.PUT_LINE(‘更新失敗!‘);    End  If;   End;   6,如何使用顯示遊標,?如何遍曆迴圈遊標?   ①使用顯示遊標    ⑴聲明遊標:劃分儲存地區,注意此時並沒有執行Select 語句。     CURSOR 遊標名( 參數 列表)   [傳回值類型]   IS   Select 語句;    ⑵開啟遊標:執行Select 語句,獲得結果集儲存到遊標中,此時遊標指向結果集頭, 而不是第一條記錄。     Open 遊標名( 參數 列表);    ⑶擷取記錄:移動遊標取一條記錄     Fetch  遊標名InTo  臨時記錄或屬性類型變數;    ⑷關閉遊標:將遊標放入緩衝池中,沒有完全釋放資源。可重新開啟。     Close  遊標名;  ②遍曆迴圈遊標   ⑴For 迴圈遊標    迴圈遊標隱式開啟遊標,自動滾動擷取一條記錄,並自動建立臨時記錄類型變數儲存記錄。處理完後自動關閉遊標。      For  變數名  In  遊標名       Loop       資料處理語句;      End Loop;    ⑵Loop迴圈遊標      。。。     Loop      Fatch  遊標名InTo  臨時記錄或屬性類型變數;      Exit  When   遊標名%NotFound;     End   Loop;      。。。   例子1:   /* conn scott/tiger */    Declare      Cursor myCur is select empno,ename,sal from emp;      vna varchar2(10);      vno number(4);      vsal number(7,2);   Begin      open myCur;      fetch myCur into vno,vna,vsal;      dbms_output.put_line(vno||‘    ‘||vna||‘    ‘||vsal);      close myCur;   End;   /    例子2:使用loop遍曆遊標。  /* conn scott/tiger */   Declare      Cursor myCur is select ename,job,sal,empno from emp;      varE myCur%rowType;   Begin      if myCur%isopen = false then         open myCur;        dbms_output.put_line(‘Opening...‘);      end if;      loop         fetch myCur into varE;         exit when myCur%notfound;         dbms_output.put_line(myCur%rowCount||‘    ‘||vare.empno||‘    ‘||vare.ename||‘    ‘||vare.sal);      end loop;      if myCur%isopen then         Close myCur;         dbms_output.put_line(‘Closing...‘);      end if;   End;   /     例子3:使用For迴圈遍曆遊標,   /* conn scott/tiger */   Declare      Cursor myCur is select * from emp;   Begin      for varA in myCur       loop          dbms_output.put_line(myCur%rowCount||‘    ‘||varA.empno||‘    ‘||varA.ename||‘  ‘||varA.sal);       end loop;   End;   /   7,怎樣更新和刪除顯示遊標中的記錄?  ①UPDATE或DELETE語句中的WHERE CURRENT OF子串專門處理要執行UPDATE或DELETE操作的表中取出的最近的資料。   要使用這個方法,在聲明遊標時必須使用FOR UPDATE子串,當對話使用FOR UPDATE子串開啟一個遊標時,   所有返回集中的資料行都將處於行級(ROW-LEVEL)獨佔式鎖定,其他對象只能查詢這些資料行,   不能進行UPDATE、DELETE或SELECT...FOR UPDATE操作。    在多表查詢中,使用OF子句來鎖定特定的表,如果忽略了OF子句,那麼所有表中選擇的資料行都將被鎖定。    如果這些資料行已經被其他會話鎖定,那麼正常情況下ORACLE將等待,直到資料行解鎖。  ②使用更新或刪除:   ⑴聲明更新或刪除顯示遊標:    Cursor 遊標名IS  SELECT 語句   For Update [ Of  更新列列名];    Cursor 遊標名IS  SELECT 語句   For Delete [ Of  更新列列名];   ⑵使用顯示遊標目前記錄來更新或刪除:    Update  表名   SET   更新語句  Where   Current  Of   遊標名;    Delete  From  表名   Where   Current  Of   遊標名;      例子1:更新顯示遊標記錄    /*conn scott/tiger*/    Declare      Cursor myCur is select job from emp for update;        vjob empa.job%type;        rsal empa.sal%type;     Begin        open myCur;        loop           fetch myCur into vjob;           exit when myCur%notFound;           case  (vjob)              when ‘ANALYST‘ then  rsal := 0.1;             when  ‘CLERK‘ then  rsal := 0.2;              when  ‘MANAGER‘ then  rsal := 0.3;              else                rsal := 0.5;           end case;         update emp set sal = sal + rsal where current of myCur;        end loop;     End;     /     例子2:刪除顯示遊標記錄     /*conn scott/tiger     Crate table  empa  Select * from scott.emp;     */     Declare       Cursor MyCursor  Select   JOB  From  empa  For  Update;       vSal   emp.Sal%TYPE;     Begin       Loop        Fetch  MyCursor  InTo  vSal;        Exit  When  MyCursor%NotFound;        If   vSal < 800 Then         Delete  From empa  Where  Cursor  Of   MyCursor;        End  If;         End    Loop;     End;/ 8,什麼是帶參數的顯示遊標?  ①與過程和函數相似,可以將參數傳遞給遊標並在查詢中使用。   參數只定義資料類型,沒有大小(所有Oracle中的形參只定義資料類型,不指定大小)。   與過程不同的是,遊標只能接受傳遞的值,而不能傳回值。    可以給參數設定一個預設值,當沒有參數值傳遞給遊標時,就使用預設值。   遊標中定義的參數只是一個預留位置,在別處引用該參數不一定可靠。  ②使用帶參數的顯示遊標   ⑴聲明帶參數的顯示遊標:    CURSOR 遊標名  [(parameter[,parameter],...)]    IS   Select語句;;       參數形式:1,參數名   資料類型          2,參數名   資料類型  DEFAULT  預設值           例子:     /*conn scott/tiger     Crate table  empa  Select * from scott.emp;     */     Declare       Cursor MyCursor(pSal  Number  Default   800)  Select   JOB  From  empa Where  SAL >  pSal ;       varA  MyCursor%ROWTYPE;     Begin       Loop        Fetch  MyCursor  InTo  varA;        Exit  When  MyCursor%NotFound;        DBMS_OUTPUT.PUT_LINE(MyCursor%RowCount||‘    ‘||varA.empno||‘    ‘||varA.ename||‘  ‘||varA.sal);        End    Loop;     End;/       REF CURSOR   1,什麼是REF遊標 ?  動態關連接果集的臨時對象。即在啟動並執行時候動態決定執行查詢。   2,REF 遊標 有什麼作用?  實現在程式間傳遞結果集的功能,利用REF CURSOR也可以實現BULK SQL,從而提高SQL效能。   3,靜態資料指標和REF 遊標的區別是什嗎?  ①靜態資料指標是靜態定義,REF 遊標是動態關聯;  ②使用REF 遊標需REF 遊標變數。  ③REF 遊標能做為參數進行傳遞,而靜態資料指標是不可能的。   4,什麼是REF 遊標變數?  REF遊標變數是一種 引用REF遊標類型  的變數,指向動態關聯的結果集。   5,怎麼使用  REF遊標 ?  ①聲明REF 遊標類型,確定REF 遊標類型;   ⑴強型別REF遊標:指定retrun type,REF 遊標變數的類型必須和return type一致。    文法:Type   REF遊標名   IS   Ref Cursor Return  結果集返回記錄類型;   ⑵弱類型REF遊標:不指定return type,能和任何類型的CURSOR變數匹配,用於擷取任何結果集。    文法:Type   REF遊標名   IS   Ref Cursor;    ②聲明Ref 遊標類型變數;   文法:變數名  已聲明Ref 遊標類型;    ③開啟REF遊標,關連接果集 ;   文法:Open   Ref 遊標類型變數   For   查詢語句返回結果集;    ④擷取記錄,操作記錄;   文法:Fatch    REF遊標名InTo   臨時記錄類型變數或屬性類型變數列表;    ⑤關閉遊標,完全釋放資源;   文法:Close   REF遊標名;    例子:強型別REF遊標  /*conn scott/tiger*/  Declare   Type MyRefCurA IS  REF CURSOR RETURN emp%RowType;   Type MyRefCurB IS  REF CURSOR RETURN emp.ename%Type;   vRefCurA  MyRefCurA;   vRefCurB  MyRefCurB;   vTempA  vRefCurA%RowType;   vTempB  vRefCurB.ename%Type;    Begin   Open  vRefCurA  For Select  *  from   emp   Where  SAL > 2000;   Loop    Fatch  vRefCurA InTo  vTempA;    Exit  When  vRefCurA%NotFound;    DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||‘  ‘|| vTempA.eno||‘  ‘||vTempA.ename ||‘  ‘||vTempA.sal)   End Loop;   Close vRefCurA;     DBMS_OUTPUT.PUT_LINE(‘-------------------------------------------------------------------------------------------------------‘);     Open  vRefCurB  For Select  ename  from   emp   Where  SAL > 2000;   Loop    Fatch  vRefCurB InTo  vTempB;    Exit  When  vRefCurB%NotFound;    DBMS_OUTPUT.PUT_LINE(vRefCurB%RowCount||‘  ‘||vTempB)   End Loop;   Close vRefCurB;     DBMS_OUTPUT.PUT_LINE(‘-------------------------------------------------------------------------------------------------------‘);       Open  vRefCurA  For Select  *  from   emp   Where  JOB = ‘CLERK‘;   Loop    Fatch  vRefCurA InTo  vTempA;    Exit  When  vRefCurA%NotFound;    DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||‘  ‘|| vTempA.eno||‘  ‘||vTempA.ename ||‘  ‘||vTempA.sal)   End Loop;   Close vRefCurA;  End;    例子:弱類型REF遊標  /*conn scott/tiger*/  Declare   Type MyRefCur  IS  Ref  Cursor;   vRefCur MyRefCur;   vtemp  vRefCur%RowType;  Begin   Case(&n)    When  1 Then Open vRefCur  For Select   *   from emp;    When  2 Then Open vRefCur  For Select   *   from dept;    Else     Open vRefCur  For Select   eno,  ename  from emp Where JOB = ‘CLERK‘;   End Case;   Close  vRefCur;  End;

 

[轉載]oracle遊標概念講解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.