標籤:style blog http os 使用 io java strong ar
Oracle 系列:REF Cursor
在上文 Oracle 系列:Cursor (參見:http://blog.csdn.net/qfs_v/archive/2008/05/06/2404794.aspx)中
提到個思考:怎樣讓遊標作為參數傳遞? 解決這個問題就需要用到 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遊標作為參數傳遞?--此處原文沒有,自己補上:
寫好預存程序,JAVA調用返回部門號為10的全部員工資訊:
1)預存程序
[sql] view plaincopy
- CREATE OR REPLACE PROCEDURE findset_emp(v_deptno IN NUMBER,
- c_cursor OUT SYS_REFCURSOR) AS
- BEGIN
- OPEN c_cursor FOR
- SELECT *
- FROM emp
- WHERE deptno = v_deptno;
- END;
2)Java調用
[java] view plaincopy
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- try{
- // load oracle driver
- Class.forName("oracle.jdbc.driver.OracleDriver");
- Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl","scott","tiger");
-
- CallableStatement cs = ct.prepareCall("{call findset_emp(?,?)}");
- cs.setInt(1, 10);
- cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
-
- cs.execute();
- ResultSet rs = (ResultSet)cs.getObject(2);
- while(rs.next()){
- System.out.println(rs.getInt(1)+" "+rs.getString(2));
- }
- cs.close();
- ct.close();
- }
- catch(Exception e){
- e.printStackTrace();
- }
3)效果如下:
-------------------------
present by dylan.
oracle ref遊標