介紹兩種遊標cursor與sys_refcursor
1、cursor遊標使用
/*簡單cursor遊標
*students表裡面有name欄位,你可以換做其他表測試
*/
--定義
declare
--定義遊標並且賦值(is 不能和cursor分開使用)
cursor stus_cur is select * from students;
--定義rowtype
cur_stu students%rowtype;
/*開始執行*/
begin
--開啟遊標
open stus_cur;
--loop迴圈
loop
--迴圈條件
exit when stus_cur%notfound;
--遊標值賦值到rowtype
fetch stus_cur into cur_stu;
--輸出
dbms_output.put_line(cur_stu.name);
--結束迴圈
end loop;
--關閉遊標
close stus_cur;
/*結束執行*/
end;
執行結果
SQL> declare
2 --定義遊標並且賦值(is 不能和cursor分開使用)
3 cursor stus_cur is select * from students;
4 --定義rowtype
5 cur_stu students%rowtype;
6 /*開始執行*/
7 begin
8 --開啟遊標
9 open stus_cur;
10 --loop迴圈
11 loop
12 --迴圈條件
13 exit when stus_cur%notfound;
14 --遊標值賦值到rowtype
15 fetch stus_cur into cur_stu;
16 --輸出
17 dbms_output.put_line(cur_stu.name);
18 --結束迴圈
19 end loop;
20 --關閉遊標
21 close stus_cur;
22 /*結束執行*/
23 end;
24 /
楊過
郭靖
付政委
劉自飛
江風
任我行
任盈盈
令狐沖
韋一笑
張無忌
朵兒
謝遜
小龍女
歐陽鋒
歐陽鋒
2、sys_refcursor遊標使用
/*
*遊標名:sys_refcursor
*特別注意賦值方式:for
*與上重複內容不在敘述
*/
declare
stu_cur sys_refcursor;
stuone students%rowtype;
begin
--這句賦值方式for
open stu_cur for select * from students;
--fetch賦值給rowtype
fetch stu_cur into stuone;
loop
dbms_output.put_line(stuone.name||' '||stuone.hobby);
fetch stu_cur into stuone;
exit when stu_cur%notfound;
end loop;
end;
執行結果
SQL> /*
2 *遊標名:sys_refcursor
3 *特別注意賦值方式:for
4 *與上重複內容不在敘述
5 */
6 declare
7 stu_cur sys_refcursor;
8 stuone students%rowtype;
9
10 begin
11 --這句賦值方式for
12 open stu_cur for select * from students;
13 --fetch賦值給rowtype
14 fetch stu_cur into stuone;
15
16 loop
17 dbms_output.put_line(stuone.name||' '||stuone.hobby);
18 fetch stu_cur into stuone;
19 exit when stu_cur%notfound;
20 end loop;
21 end;
22 /
楊過 保護小龍女
郭靖 修煉降龍十八掌
付政委 看小人書
劉自飛 程式設計寫程式碼
江風 程式設計寫程式碼
任我行 修煉神功
任盈盈 遊山玩水
令狐沖 行俠仗義
韋一笑 吸拾人雪
張無忌 修行
朵兒 洗浴
謝遜 畢生研究屠龍刀
小龍女 修煉玉女心經
歐陽鋒 看小人書
補充一種迴圈條件
declare
stu_cur sys_refcursor;
stuone students%rowtype;
begin
open stu_cur for select * from students;
fetch stu_cur into stuone;
--特別注意迴圈條件的改變
--這個條件是發現了在迴圈
--與上一個notfound不同的
while stu_cur%found loop
dbms_output.put_line(stuone.name||' '||stuone.hobby);
fetch stu_cur into stuone;
end loop;
end;
oracle中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;
6,怎樣讓REF遊標作為引數傳遞?
程式碼如下
--作為函式返回值
create or replace function returnacursor return sys_refcursor
is
v_csr sys_refcursor;
begin
open v_csr for select a1 from test3;
return v_csr;
end;
/
declare
c sys_refcursor;
a1 char(2);
begin
c:=returnacursor;
loop
fetch c into a1;
exit when c%notfound;
dbms_output.put_line(a1);
end loop;
close c;
end;
/
--作為引數
create or replace procedure proc_ref_cursor (rc in sys_refcursor) as
v_a number;
v_b varchar2(10);
begin
loop
fetch rc into v_a, v_b;
exit when rc%notfound;
dbms_output.put_line(v_a || ' ' || v_b);
end loop;
end;
/
declare
v_rc sys_refcursor;
begin
open v_rc for
select a1,a2 from test3;
proc_ref_cursor(v_rc);
close v_rc;
end;
/
REF CURSOR 示例包括下列三個 Visual Basic 示例,演示如何使用 REF CURSOR。
示例 說明
在 OracleDataReader
中檢索 REF CURSOR 引數
此示例執行一個 PL/SQL 儲存過程,返回 REF CURSOR 引數,並將值作為 OracleDataReader
讀取。
使用 OracleDataReader
從多個 REF CURSOR 檢索資料
此示例執行一個 PL/SQL 儲存過程,返回兩個 REF CURSOR 引數,並使用 OracleDataReader
讀取值。
使用一個或多個 REF CURSOR 填充 DataSet
此示例執行一個 PL/SQL
儲存過程,返回兩個 REF CURSOR 引數,並使用返回的行填充 DataSet
。
要使用這些示例,可能需要建立 Oracle 表,並且必須建立 PL/SQL 包和包正文。
建立 Oracle 表
這些示例使用 Oracle Scott/Tiger
架構中定義的表。大多數 Oracle 安裝均包括 Oracle Scott/Tiger 架構。如果此架構不存在,可以使用 {OracleHome}rdbmsadminscott.sql
中的 SQL 命令檔案建立供這些示例使用的表和索引。
建立 Oracle 包和包正文
這些示例要求伺服器上存在以下 PL/SQL 包和包正文。在 Oracle
伺服器上建立以下 Oracle 包
程式碼如下
CREATE OR REPLACE PACKAGE BODY CURSPKG AS
PROCEDURE OPEN_ONE_CURSOR (N_EMPNO IN NUMBER,
IO_CURSOR IN OUT T_CURSOR)
IS
V_CURSOR T_CURSOR;
BEGIN
IF N_EMPNO <> 0
THEN
OPEN V_CURSOR FOR
SELECT EMP.EMPNO, EMP.ENAME, DEPT.DEPTNO, DEPT.DNAME
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO
AND EMP.EMPNO = N_EMPNO;
ELSE
OPEN V_CURSOR FOR
SELECT EMP.EMPNO, EMP.ENAME, DEPT.DEPTNO, DEPT.DNAME
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;
END IF;
IO_CURSOR := V_CURSOR;
END OPEN_ONE_CURSOR;
PROCEDURE OPEN_TWO_CURSORS (EMPCURSOR OUT T_CURSOR,
DEPTCURSOR OUT T_CURSOR)
IS
V_CURSOR1 T_CURSOR;
V_CURSOR2 T_CURSOR;
BEGIN
OPEN V_CURSOR1 FOR SELECT * FROM EMP;
OPEN V_CURSOR2 FOR SELECT * FROM DEPT;
EMPCURSOR := V_CURSOR1;
DEPTCURSOR := V_CURSOR2;
END OPEN_TWO_CURSORS;
END CURSPKG;
/
Oracle提供REF CURSOR
,通過該功能可以實現在程式間傳遞結果集的功能,利用REF CURSOR
也可以實現BULK SQL
,從而提高SQL
效能。
使用scott使用者的emp表實現以下測試案例:
程式碼如下
SQL> desc emp
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
使用ref cursor獲得結果集輸出:
SQL> set serveroutput on
SQL> DECLARE
2 TYPE mytable IS TABLE OF emp%ROWTYPE;
3 l_data mytable;
4 l_refc sys_refcursor;
5 BEGIN
6 OPEN l_refc FOR
7 SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno FROM emp;
8
9 FETCH l_refc BULK COLLECT INTO l_data;
10
11 CLOSE l_refc;
12
13 FOR i IN 1 .. l_data.COUNT
14 LOOP
15 DBMS_OUTPUT.put_line ( l_data (i).ename
16 || ' was hired since '
17 || l_data (i).hiredate
18 );
19 END LOOP;
20 END;
21 /
SMITH was hired since 17-DEC-80
ALLEN was hired since 20-FEB-81
WARD was hired since 22-FEB-81
JONES was hired since 02-APR-81
MARTIN was hired since 28-SEP-81
BLAKE was hired since 01-MAY-81
CLARK was hired since 09-JUN-81
SCOTT was hired since 19-APR-87
KING was hired since 17-NOV-81
TURNER was hired since 08-SEP-81
ADAMS was hired since 23-MAY-87
JAMES was hired since 03-DEC-81
FORD was hired since 03-DEC-81
MILLER was hired since 23-JAN-82
PL/SQL procedure successfully completed.
-The End-
相關文章
- 【CURSOR】Oracle 遊標 (cursor)知識梳理Oracle
- SYS_REFCURSOR系統遊標的使用
- MyBatis 與 SpringBoot 整合:註解和xml兩種使用方式介紹MyBatisSpring BootXML
- Oracle資料庫之cursor、refcursor及sys_refcursor深度解析Oracle資料庫
- flask-sqlalchemy中使用cursor遊標FlaskSQL
- python遊戲引擎ppb介紹(2)精靈、場景與座標Python遊戲引擎
- 簡單介紹MySQL開啟事務的兩種方式MySql
- Redis持久化的兩種方式的優缺點介紹Redis持久化
- eyoucms標籤介紹
- 簡單介紹python連線telnet和ssh的兩種方式Python
- 元宇宙鏈遊開發與介紹元宇宙
- Go 標準庫之 GoRequests 介紹與基本使用Go
- 初始化引數遊標之cursor_sharing
- 簡單介紹Golang列印複雜結構體的兩種方法Golang結構體
- Redis學習 RDB和AOF兩種持久化介紹以及實現Redis持久化
- Machine Learning (3) - 介紹兩種儲存和讀取模型的方式Mac模型
- HTML常用標籤介紹HTML
- Go 常用標準庫之 fmt 介紹與基本使用Go
- LIBGDX遊戲引擎平臺介紹與搭建遊戲引擎
- JSP 自定義標籤介紹JS
- canvas標籤簡單介紹Canvas
- 野村哲也訪談:《FF7 RE 過渡版》與兩款手遊的全面介紹
- 幾種新DevOps工具介紹dev
- 直播商城原始碼,android執行緒的介紹及兩種啟動方式原始碼Android執行緒
- Android學習過程的Cursor遊標填坑筆記Android筆記
- LVS介紹與配置
- NFS介紹與搭建NFS
- GoogleTagManager 介紹與使用Go
- Influxdb 介紹與使用UX
- 小程式開發標準流程與費用明細介紹
- 個人介紹以及希望目標
- Linux系統安裝執行.AppImage檔案的兩種執行方法介紹LinuxAPP
- Java中15種鎖的介紹Java
- Windows Server 2016各種版本介紹WindowsServer
- MongoDB三種聚合命令用法介紹MongoDB
- 【CSS: cursor】滑鼠游標指標樣式大全CSS指標
- UDP 和 TCP 兩種協議簡介UDPTCP協議
- redis介紹與安裝Redis