您的位置:首页 > 数据库 > Oracle

DB2与oracle游标定义的区别

2016-06-02 18:39 861 查看

1、游标的介绍:

1.oracle游标介绍:

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游标名;

/*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-

2.DB2游标介绍

DB2游标原理对于很多刚刚接触DB2数据库的新人来说,还比较陌生,下面就为您详细介绍DB2游标原理,希望让您对DB2游标原理有更多的了解。

DB2游标原理

一般情况下,SQL查询结果都是多条纪录的结果集,而高级语言一次只能处理一条纪录,用游标机制,将多条纪录一次一条读取出来处理。从而把对集合的操作转化为对单个纪录的处理。游标使用的步骤如下:

1、说明游标。说明游标的时候并不执行select语句。

declare <游标名> cursor for <select语句>;

2、打开游标。打开游标实际上是执行相应的select语句,把查询结果读取到缓冲区中。这时候游标处于活动状态,指针指向查询结果集的第一条纪录。

open <游标名>;

3、推进游标指针并读取当前纪录。用fetch语句把游标指针向前推进一条纪录,同时将缓冲区中的当前纪录读取出来送到变量中。fetch语句通常用在一个循环结构体中,通过循环执行fetch语句逐条取出结果集中的行进行处理。现在好多数据库中,还允许任意方向任意步长易懂游标指针,而不仅仅是把游标指针向前推进一行了。

fetch <游标名> into <变量1>,<变量2>...

4、关闭游标。用close语句关闭游标,释放结果集占用的缓冲区及其他资源。游标关闭后,就不再和原来的查询结果集相联系。但游标可以再次打开,与新的查询结果相联系。

close <游标名>;

DB2游标的循环控制   

DB2下游标控制不是非常的轻松和方便的,也可以使用sqlcode,sqlstate来控制,或者用户自己控制,DB2下SQLCODE,SQLSTATE不能直接使用,必须声明后使用,(也就是说将系统的SQLCODE,SQLSTATE本地实例化一分拷贝)。一般采用用户定义游标开关和sqlcode返回信息一起共同控制的方法.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  oracle游标 db2游标