生活随笔
收集整理的這篇文章主要介紹了
Oracle中Cursor介绍
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一? 概念 游標是SQL的一個內存工作區,由系統或用戶以變量的形式定義。游標的作用就是用于臨時存儲從數據庫中提取的數據塊。在某些情況下,需要把數據從 存放在磁盤的表中調到計算機內存中進行處理,最后將處理結果顯示出來或最終寫回數據庫。這樣數據處理的速度才會提高,否則頻繁的磁盤數據交換會降低效率。
二? 類型 ? Cursor類型包含三種: 隱式Cursor,顯式Cursor和Ref Cursor(動態Cursor)。 1. 隱式Cursor: 1).對于Select …INTO…語句,一次只能從數據庫中獲取到一條數據,對于這種類型的DML Sql語句,就是隱式Cursor。例如:Select /Update / Insert/Delete操作。 2)作用:可以通過隱式Cusor的屬性來了解操作的狀態和結果,從而達到流程的控制。Cursor的屬性包含: SQL%ROWCOUNT 整型 代表DML語句成功執行的數據行數 SQL%FOUND? 布爾型? 值為TRUE代表插入、刪除、更新或單行查詢操作成功 SQL%NOTFOUND 布爾型 與SQL%FOUND屬性返回值相反 SQL%ISOPEN 布爾型 DML執行過程中為真,結束后為假 3) 隱式Cursor是系統自動打開和關閉Cursor.
Set Serveroutput on; begin ??? update t_contract_master set liability_state = 1 where policy_code = '123456789'; ??? if SQL%Found then ?????? dbms_output.put_line('the Policy is updated successfully.'); ?????? commit; ??? else ????? dbms_output.put_line('the policy is updated failed.'); ??? end if; end; /
在PL/SQL中run:
Sql代碼 ?
SQL>??? ??? the?policy?is ?updated?failed.?? ??? PL/SQL?procedure ?successfully?completed 2. 顯式Cursor: (1) 對于從數據庫中提取多行數據,就需要使用顯式Cursor。顯式Cursor的屬性包含: 游標的屬性?? 返回值類型?? 意??? 義? %ROWCOUNT?? 整型? 獲得FETCH語句返回的數據行數? %FOUND? 布爾型 最近的FETCH語句返回一行數據則為真,否則為假? %NOTFOUND?? 布爾型 與%FOUND屬性返回值相反? %ISOPEN 布爾型 游標已經打開時值為真,否則為假? (2) 對于顯式游標的運用分為四個步驟: ? 定義游標---Cursor? [Cursor Name]? IS; ? 打開游標---Open? [Cursor Name]; ? 操作數據---Fetch? [Cursor name] ? 關閉游標---Close [Cursor Name],這個Step絕對不可以遺漏。 (3)以下是三種常見顯式Cursor用法。 1)
Sql代碼 ?
Set ?serveroutput?on ;???? declare ????????? ????Cursor ?cur_policy?is ?? ?????select ?cm.policy_code,?cm.applicant_id,?cm.period_prem,cm.bank_code,cm.bank_account?? ?????from ?t_contract_master?cm?? ?????where ?cm.liability_state?=?2?? ?????and ?cm.policy_type?=?1?? ?????and ?cm.policy_cate?in ?('2' ,'3' ,'4' )?? ?????and ?rownum?<?5?? ?????order ?by ?cm.policy_code?desc ;?? ????curPolicyInfo?cur_policy%rowtype;?? Begin ?????open ?cur_policy;??? ???Loop??? ??????? ?????Fetch ?cur_policy?into ?curPolicyInfo;?? ?????Exit?when ?cur_policy%notfound;?? ??????????? ?????Dbms_Output.put_line(curPolicyInfo.policy_code);?? ???end ?loop;?? ???Exception??? ?????when ?others?then ?? ?????????close ?cur_policy;?? ?????????Dbms_Output.put_line(Sqlerrm);?? ??????????? ???if?cur_policy%isopen?then ???? ?????? ??????close ?cur_policy;?? ???end ?if;?? end ;???? /?? 2)
Sql代碼 ?
Set ?serveroutput?on ;???? declare ???????Cursor ?cur_policy?is ?? ?????select ?cm.policy_code,?cm.applicant_id,?cm.period_prem,cm.bank_code,cm.bank_account?? ?????from ?t_contract_master?cm?? ?????where ?cm.liability_state?=?2?? ?????and ?cm.policy_type?=?1?? ?????and ?cm.policy_cate?in ?('2' ,'3' ,'4' )?? ?????and ?rownum?<?5?? ?????order ?by ?cm.policy_code?desc ;?? ?????v_policyCode?t_contract_master.policy_code%type;?? ?????v_applicantId?t_contract_master.applicant_id%type;?? ?????v_periodPrem?t_contract_master.period_prem%type;?? ?????v_bankCode?t_contract_master.bank_code%type;?? ?????v_bankAccount?t_contract_master.bank_account%type;?? Begin ?????open ?cur_policy;?? ???Loop??? ?????Fetch ?cur_policy?into ?v_policyCode,?? ???????????????????????????v_applicantId,?? ???????????????????????????v_periodPrem,?? ???????????????????????????v_bankCode,?? ???????????????????????????v_bankAccount;?? ?????Exit?when ?cur_policy%notfound;?? ??????????? ?????Dbms_Output.put_line(v_policyCode);?? ???end ?loop;?? ???Exception??? ?????when ?others?then ?? ?????????close ?cur_policy;?? ?????????Dbms_Output.put_line(Sqlerrm);?? ??????????? ???if?cur_policy%isopen?then ????? ??????close ?cur_policy;?? ???end ?if;?? end ;??/?? 3)
Sql代碼 ?
Set ?serveroutput?on ;???? declare ???????Cursor ?cur_policy?is ?? ?????select ?cm.policy_code,?cm.applicant_id,?cm.period_prem,cm.bank_code,cm.bank_account?? ?????from ?t_contract_master?cm?? ?????where ?cm.liability_state?=?2?? ?????and ?cm.policy_type?=?1?? ?????and ?cm.policy_cate?in ?('2' ,'3' ,'4' )?? ?????and ?rownum?<?5?? ?????order ?by ?cm.policy_code?desc ;?? Begin ?????For ?rec_Policy?in ?cur_policy?loop?? ???????Dbms_Output.put_line(rec_policy.policy_code);?? ???end ?loop;?? ???Exception??? ?????when ?others?then ?? ?????????Dbms_Output.put_line(Sqlerrm);?? ??????????? end ;???? /?? run pl/sql,執行結果如下:
Sql代碼 ?
SQL>??? ??? 8780203932?? 8780203227?? 8780203218?? 8771289268?? ??? PL/SQL?procedure ?successfully?completed?? 3. Ref Cursor(動態游標): 1) 與隱式Cursor,顯式Cursor的區別:Ref Cursor是可以通過在運行期間傳遞參數來獲取數據結果集。而另外兩種Cursor,是靜態的,在編譯期間就決定數據結果集。 2) Ref cursor的使用: ? Type [Cursor type name] is ref cursor ? Define 動態的Sql語句 ? Open cursor ? 操作數據---Fetch? [Cursor name] ? Close Cursor 下面是一個Sample:
Sql代碼 ?
Set ?serveroutput?on ;???? Declare ???????? ????type?cur_type?is ?ref?cursor ;?? ????cur_policy?cur_type;?? ????sqlStr?varchar2(500);?? ????rec_policy?t_contract_master%rowtype;?? begin ??????? ???sqlStr?:=?'select ?cm.policy_code,?cm.applicant_id,?cm.period_prem,cm.bank_code,cm.bank_account?from ?t_contract_master?cm?? ?????where ?cm.liability_state?=?2??? ?????and ?cm.policy_type?=?1??? ?????and ?cm.policy_cate?in ?(2,3,4)??? ?????and ?rownum?<?5??? ?????order ?by ?cm.policy_code?desc ?';?? ?? ??open ?cur_policy?for ?sqlStr;?? ??loop?? ???????fetch ?cur_policy?into ?rec_policy.policy_code,?rec_policy.applicant_id,?rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account;?? ???????exit?when ?cur_policy%notfound;?? ????????? ???????Dbms_Output.put_line('Policy_code:' ||rec_policy.policy_code);?? ???? ??end ?loop;?? close ?cur_policy;???????? end ;??/?? 4.常見Exception
Sql代碼 ?
1.??錯?誤?名?稱?錯誤代碼????錯?誤?含?義????? 2.??CURSOR_ALREADY_OPEN?ORA_06511???試圖打開已經打開的游標????? 3.??INVALID_CURSOR??ORA_01001???試圖使用沒有打開的游標????? 4.??DUP_VAL_ON_INDEX????ORA_00001???保存重復值到惟一索引約束的列中????? 5.??ZERO_DIVIDE?ORA_01476???發生除數為零的除法錯誤????? 6.??INVALID_NUMBER??ORA_01722???試圖對無效字符進行數值轉換????? 7.??ROWTYPE_MISMATCH????ORA_06504???主變量和游標的類型不兼容????? 8.??VALUE_ERROR?ORA_06502???轉換、截斷或算術運算發生錯誤????? 9.??TOO_MANY_ROWS???ORA_01422???SELECT …INTO …語句返回多于一行的數據????? 10.?NO_DATA_FOUND???ORA_01403???SELECT …INTO …語句沒有數據返回????? 11.?TIMEOUT_ON_RESOURCE?ORA_00051???等待資源時發生超時錯誤????? 12.?TRANSACTION_BACKED_OUT??ORA_00060???由于死鎖,提交失敗????? 13.?STORAGE_ERROR???ORA_06500???發生內存錯誤????? 14.?PROGRAM_ERROR???ORA_06501???發生PL/SQL內部錯誤????? 15.?NOT_LOGGED_ON???ORA_01012???試圖操作未連接的數據庫????? 16.?LOGIN_DENIED????ORA_01017???在連接時提供了無效用戶名或口令?
總結
以上是生活随笔 為你收集整理的Oracle中Cursor介绍 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。