oracle的cursor的介绍
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.
下面是一個Sample:
Sql代碼
1.?? Set?Serveroutput?on; ??
2.?? ??
3.?? begin??
4.?? ????update?t_contract_master?set?liability_state?=?1?where?policy_code?=?'123456789'; ??
5.?? ???? ??
6.?? ????if?SQL%Found?then??
7.?? ???????dbms_output.put_line('the?Policy?is?updated?successfully.'); ??
8.?? ???????commit; ??
9.?? ????else??
10.? ??????dbms_output.put_line('the?policy?is?updated?failed.'); ??
11.? ????end?if; ????
12.? end; ????
13.? /??
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代碼
1.?? SQL>? ??? ??
2.?? the?policy?is?updated?failed. ??? ??
3.? PL/SQL?procedure?successfully?completed??
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代碼
1.?? Set?serveroutput?on; ??
2.?? ??
3.?? declare? ??
4.?? ????---define?Cursor ??
5.?? ????Cursor?cur_policy?is??
6.?? ?????select?cm.policy_code,?cm.applicant_id,?cm.period_prem,cm.bank_code,cm.bank_account ??
7.?? ?????from?t_contract_master?cm ??
8.?? ?????where?cm.liability_state?=?2 ??
9.?? ?????and?cm.policy_type?=?1 ??
10.? ?????and?cm.policy_cate?in?('2','3','4') ??
11.? ?????and?rownum?<?5 ??
12.? ?????order?by?cm.policy_code?desc; ??
13.? ????curPolicyInfo?cur_policy%rowtype;---定義游標變量 ??
14.? Begin??
15.? ???open?cur_policy;?---open?cursor ??
16.? ???Loop? ??
17.? ?????--deal?with?extraction?data?from?DB ??
18.? ?????Fetch?cur_policy?into?curPolicyInfo; ??
19.? ?????Exit?when?cur_policy%notfound; ??
20.? ????????? ??
21.? ?????Dbms_Output.put_line(curPolicyInfo.policy_code); ??
22.? ???end?loop; ??
23.? ???Exception? ??
24.? ?????when?others?then??
25.? ?????????close?cur_policy; ??
26.? ?????????Dbms_Output.put_line(Sqlerrm); ??????????? ??
27.? ???if?cur_policy%isopen?then?? ??
28.? ????--close?cursor? ??
29.? ??????close?cur_policy; ??
30.? ???end?if; ??
31.? end; ????
32.? /??
Set serveroutput on;
?
declare
??? ---define Cursor
??? 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; ---open cursor
?? Loop
???? --deal with extraction data from DB
???? 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 cursor
????? close cur_policy;
?? end if;
end;
?
/
2)
Sql代碼
1.?? Set?serveroutput?on; ??
2.?? ??
3.?? declare? ??
4.?? ????Cursor?cur_policy?is??
5.?? ?????select?cm.policy_code,?cm.applicant_id,?cm.period_prem,cm.bank_code,cm.bank_account ??
6.?? ?????from?t_contract_master?cm ??
7.?? ?????where?cm.liability_state?=?2 ??
8.?? ?????and?cm.policy_type?=?1 ??
9.?? ?????and?cm.policy_cate?in?('2','3','4') ??
10.? ?????and?rownum?<?5 ??
11.? ?????order?by?cm.policy_code?desc; ??
12.? ?????v_policyCode?t_contract_master.policy_code%type; ??
13.? ?????v_applicantId?t_contract_master.applicant_id%type; ??
14.? ?????v_periodPrem?t_contract_master.period_prem%type; ??
15.? ?????v_bankCode?t_contract_master.bank_code%type; ??
16.? ?????v_bankAccount?t_contract_master.bank_account%type; ??
17.? Begin??
18.? ???open?cur_policy; ??
19.? ???Loop? ??
20.? ?????Fetch?cur_policy?into?v_policyCode, ??
21.? ???????????????????????????v_applicantId, ??
22.? ???????????????????????????v_periodPrem, ??
23.? ???????????????????????????v_bankCode, ??
24.? ???????????????????????????v_bankAccount; ??
25.? ?????Exit?when?cur_policy%notfound; ??
26.? ????????? ??
27.? ?????Dbms_Output.put_line(v_policyCode); ??
28.? ???end?loop; ??
29.? ???Exception? ??
30.? ?????when?others?then??
31.? ?????????close?cur_policy; ??
32.? ?????????Dbms_Output.put_line(Sqlerrm); ??????????? ??
33.? ???if?cur_policy%isopen?then??? ??
34.? ??????close?cur_policy; ??
35.? ???end?if; ??
36.? end; ??
37.? /??
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代碼
1.?? Set?serveroutput?on; ??
2.?? ??
3.?? declare? ??
4.?? ????Cursor?cur_policy?is??
5.?? ?????select?cm.policy_code,?cm.applicant_id,?cm.period_prem,cm.bank_code,cm.bank_account ??
6.?? ?????from?t_contract_master?cm ??
7.?? ?????where?cm.liability_state?=?2 ??
8.?? ?????and?cm.policy_type?=?1 ??
9.?? ?????and?cm.policy_cate?in?('2','3','4') ??
10.? ?????and?rownum?<?5 ??
11.? ?????order?by?cm.policy_code?desc; ??
12.? Begin??
13.? ???For?rec_Policy?in?cur_policy?loop ??
14.? ???????Dbms_Output.put_line(rec_policy.policy_code); ??
15.? ???end?loop; ??
16.? ???Exception? ??
17.? ?????when?others?then??
18.? ?????????Dbms_Output.put_line(Sqlerrm); ????????? ??
19.? end; ??
20.? ??
21.? /??
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代碼
1.?? SQL>? ??? ??
2.?? 8780203932 ??
3.?? 8780203227 ??
4.?? 8780203218 ??
5.?? 8771289268 ??? ??
6.? PL/SQL?procedure?successfully?completed??
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代碼
1.?? Set?serveroutput?on; ??
2.?? ??
3.?? Declare??
4.?? ????---define?cursor?type?name ??
5.?? ????type?cur_type?is?ref?cursor; ??
6.?? ????cur_policy?cur_type; ??
7.?? ????sqlStr?varchar2(500); ??
8.?? ????rec_policy?t_contract_master%rowtype; ??
9.?? begin??
10.? ???---define?動態Sql ??
11.? ???sqlStr?:=?'select?cm.policy_code,?cm.applicant_id,?cm.period_prem,cm.bank_code,cm.bank_account?from?t_contract_master?cm ??
12.? ?????where?cm.liability_state?=?2? ??
13.? ?????and?cm.policy_type?=?1? ??
14.? ?????and?cm.policy_cate?in?(2,3,4)? ??
15.? ?????and?rownum?<?5? ??
16.? ?????order?by?cm.policy_code?desc?'; ??
17.? ---Open?Cursor ??
18.? ??open?cur_policy?for?sqlStr; ??
19.? ??loop ??
20.? ???????fetch?cur_policy?into?rec_policy.policy_code,?rec_policy.applicant_id,?rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account; ??
21.? ???????exit?when?cur_policy%notfound; ???????? ??
22.? ???????Dbms_Output.put_line('Policy_code:'||rec_policy.policy_code); ??? ??
23.? ??end?loop; ??
24.? close?cur_policy;?????
25.? end; ??
26.? /??Set serveroutput on;
?
Declare
??? ---define cursor type name
??? type cur_type is ref cursor;
??? cur_policy cur_type;
??? sqlStr varchar2(500);
??? rec_policy t_contract_master%rowtype;
begin
?? ---define 動態Sql
?? 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 Cursor
? 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???在連接時提供了無效用戶名或口令
??
?
?是從這篇文章轉載的:http://www.javaeye.com/topic/649874
轉載于:https://www.cnblogs.com/emmy/archive/2011/01/10/1931699.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的oracle的cursor的介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Python核心编程》第二版第36页第
- 下一篇: 年底怎样才能“被评优”