`

游标以及游标变量

阅读更多
一. PL/SQL 是用游标来管理 SQL 的 SELECT 语句的 . 游标是为了处理这些语句而分配的一大块内存 . 它提供了对一个结果集进行逐行处理的能力 , 可看作是一种特殊的指针 . 它与某个查询结果集相关联 , 可以指向结果集的任意位置 , 以便对指定位置的数据进行处理 . 使用它可以在查询数据的同时对数据进行处理 .

二. 游标的分类 : 静态游标和动态游标

   1. 在说明游标分类之前, 先说明一下PL/SQL 的两个操作, 游标属性, 变量属性

SET SERVEROUTPUT ON ;-- 此语句用于开启打印输出功能

DMBS_OUTPUT.PUT_LINE();-- 打印输出并换行.

%FOUND: 判断当前游标是否指向有效的一条行记录. 是则返回TRUE, 否则返回FALSE

%NOTFOUND: 与%FOUND 恰好相反.

%ISOPEN: 判断游标是否打开, 打开则返回TRUE, 否则返回FALSE.

%ROWCOUNT: 判断当前游标在所指向的结果集中提取的行数. 并非所有总记录数

%TYPE: 声明变量的类型与表中的某列的数据类型完全一致.%TYPE 声明有两个好处: 一是你不必知道某列的确切数据类型二是当某列的数据类型改变时不用修改变量的数据类型.

%ROWTYPE: 声明变量的数据类型与表中的行记录数据类型一致. 对于自定义的记录, 则必须声明自己的域.

  2. 静态游标:

静态游标又可以分为两类:

1) 隐式游标

隐式游标的特点:

- 隐式游标是由PL/SQL 来管理的, 即不需要声明游标语句, 也不需要OPEN,FETCH,CLOSE 操作

- 隐式游标中必须要有select cur_name into [ 变量名或其他数据类型]. 此句完成OPEN,FETCH,CLOSE 操作.

- 隐式游标只能返回一行记录, 如果无符合条件的记录将会出现NO_DATA_FOUND 异常. 如果出现多条记录将出现TOO_MANY_ROWS 异常.

- 隐式游标只能用SQL% 判断其游标属性

- 对于任何位置使用SQL%ISOPEN 结果都是FALSE, 隐式游标由PL/SQL 管理

- 对于在隐式游标位置前使用SQL%FOUND 或SQL%NOTFOUND, SQL%ROWCOUNT 结果值是NULL( 不确定值)

示例表:

表名:test

字段名
数据类型
可否为空

id( 序号)
number
N

name( 姓名)
varchar2(20)
N

zym( 专业名)
varchar(40)
Y

cj( 成绩)
number
Y

logdate( 记录日期)
date
Y


EG1: 验证隐式游标的特性

  set serveroutput on;-- 开启输出

declare

  no test.id%type;-- 声明变量no 的数据类型同test 表的id 列一致

  ename test.name%type;

  begin

  if sql%isopen then         -- 判断游标是否打开

  dbms_output.put_line(' cursor is openning');

  else

  dbms_output.put_line('cursor is closed');

  end if;

if sql%notfound then – 判断游标是否指向有效的行

  dbms_output.put_line('no value');

  else

  dbms_output.put_line(no||' '||ename);

  end if;

dbms_output.put_line(sql%rowcount);

dbms_output.put_line('---------------');

/** 去掉where 条件时, 将会出现too_many_rows 异常**/

  select id ,name into no ,ename from test where cj=90;-- 隐式游标必-- 须使用INTO

  dbms_output.put_line(sql%rowcount);

  if sql%isopen then

  dbms_output.put_line(' cursor is openning');

  else

  dbms_output.put_line('cursor is closed');

  end if;

  if sql%notfound then

  dbms_output.put_line('no value');

  else

  dbms_output.put_line(no||' '||ename);

  end if;

  exception

  when no_data_found then

     dbms_output.put_line('no value');

when too_many_rows then

      dbms_output.put_line('too many rows');

  end;

执行结果为:

cursor is closed

--------------------

1

cursor is closed

1001 qbnajj

去掉where 条件时的结果:

cursor is closed

--------------------

too many rows

EG2: 使用%ROWTYPE

declare

  rowtype test%rowtype;

  begin

  select * into rowtype from test where cj=90;

  dbms_output.put_line(rowtype.name||' '||rowtype.cj);

  exception

  when no_data_found then

     dbms_output.put_line('no value');

  when too_many_rows then

      dbms_output.put_line('too many rows');

  end;

执行结果:

qbnajj 90

EG3: 自定义RECORD 数据类型

declare

/** 自定义RECORD 数据类型

  语法为:

  TYPE type_name IS RECORD(cloumn1 datatpe,.....);

**/

  type r_type is record(name test.name%type ,cj test.cj%type);

  re_type r_type;

  begin

  select name,cj into re_type from test where cj=90;

  dbms_output.put_line(re_type.name||' '||re_type.cj);

  exception

  when no_data_found then

     dbms_output.put_line('no value');

  when too_many_rows then

      dbms_output.put_line('too many rows');

  end;

/

执行结果:

qbnajj 90

2) 显示游标

声明语法:

DECLARE

CURSOR cur_name( 参数名 数据类型) is select_satatements ;-- 游标名后-- 可带参数

BEGIN

OPEN cur_name;

FETCH cur_name into [ 变量或者其他数据类型];

-- 可用循环语句迭代输出游标所指向的结果集.

CLOSE cur_name;

END;

显示游标特性:

- 显示游标由用户定义, 并由用户来管理游标, 可返回多行记录.

- 通常使用显示游标需要遵守以下规则

   声明游标 -> 打开游标 -> 读取数据 -> 关闭游标

    但由于FOR IN LOOP 语句包含OPEN,FETCH,CLOSE 操作所以不在此例.

  - 查看游标属性时, 使用cur_name%.

EG:PL/SQL 演示

declare

  no test.id%type;

  ename test.name%type;

  cjs test.cj%type;

  cursor test_cur is

  select id,name from test where cj>=cjs;-- 可通过PL/SQL 绑定变量输-- 入值(&cjs)

  begin

  cjs:=50;

  for t_cur in test_cur

  loop

  no:=t_cur.id;

  ename:=t_cur.name;

  dbms_output.put_line(no||' '||ename);

  end loop;

  end;

执行结果:

chenjunhua 80

qbnajj 90

cjh 52

EG2: 利用带参数的存储过程演示

create or replace procedure test_proce(cjs in test.cj%type)

  as

  no test.id%type;

  ename test.name%type;

  cursor test_cur is

  select id,name from test where cj>=cjs;

  begin

  open test_cur;

  fetch test_cur into no,ename;

  while test_cur%found

  loop

  dbms_output.put_line(no||' '||ename);

  fetch test_cur into no,ename;-- 将游标指向下条记录, 否则为死循环.

  end loop;

  close test_cur;

  end test_proce;

  exec test_proce(50);

执行结果:

chenjunhua 80

qbnajj 90

cjh 52

EG3: 带参数的游标与上面的类似

2. 动态游标(REF CURSOR)

首先 , 游标变量和游标是两个不同的概念 . 与游标相似 , 游标变量是指向多行查游标询的结果集的当前行 . 游标是静态的 , 游标变量是动态的 ,. 同时游标变量并不参与与特定的查询绑定 , 所以可以为任何兼容的查询打开游标变量 , 从而提高灵活性 . 而且 , 还可以将新的值赋予游标变量 , 将它作为参数传递给本地和存储过程 . 游标变量针对每个 PL/SQL 用户都是可用的 , 可以在客户端完全使用游标变量 .ORACLE 服务器同样包含 PL/SQL 引擎 , 可以将游标变量在应用和服务器之间进行传递 .

1. 游标变量 : 声明游标实际上是创建一个指针 , 指针具有数据类型 REF X.REF 是 REFERENCE ,X 是表示类对象 . 因此 , 游标变量具有数据类型 REF  CURSOR.

注 : 游标总是指向相同的查询工作区 , 游标变量能够指向不同的工作区 , 因此游标和游标变量不能互操作 .

3. 定义 REF CURSOR 类型 , 创建游标变量有两个步骤 :

  1) 定义 REF CURSOR 类型

  语法格式 :

  TYPE ref_type_name

  IS

  REF CURSOR [RETURN return_type]

  说明 :

  ref_type_name 是游标变量中使用的类型 ;return_type 必须是一个记录 (record) 或者数据库表中的一行 .(rowtype)

  下面定义 一个 REF CURSOR 类型游标

  DELARE

   TYPE xs_cur

  IS

  REF CURSOR RETURN xs%ROWTYPE;

  注意 :

  REF CURSOR 类型既可以是强类型 , 也可以是弱类型 , 区别是强类型有返回类型 , 弱类型没有 . 如下所示

   DECLARE

            TYPE xs_cur IS REF CURSOR RETURN xs%ROWTYPE;-- 强类型

            TYPE mycur IS REF CURSOR;-- 弱类型

2) 声明这种类型的游标变量 : 一旦定义了 REF CURSOR 类型就可以在 PL/SQL 块或子程序中声明这个游标变量 . 如 :

  DECARE

   TYPE xs_cur REF CURSOR RETURN xs%ROWTYPE;

   xscur xs_cur;

   当然 , 在 RETURN 子句中也可以定义自定义的 RECORD 类型 , 如 :

   DECLARE

           TYPE kc_cj IS RECORD

           (

            kch number (4),

            kcm number(10),

            cj  number(4,2)

);

TYPE kc_cjcur IS REF CURSOR RETURN kc_cj;

此外 , 也可以声明游标变量作为函数和过程的参数 . 例如 :

DECLARE

       TYPE xs_cur IS REF CURSOR RETURN xs%ROWTYPE;

       PROCEDURE open_xs (xscur IN OUT xs_cur)IS

       ......................

3. 控制游标变量

  使用游标变量时 , 要遵循以下步骤 :OPEN-FETCH-CLOSE

  OPEN 语句与多行查询的游标变量相关联 , 它执行查询 , 标志结果集

  语法格式 :

  OPEN {cursor_variable|:host_cursor_variable }FOR

  {

select_statement|dynamic_string[USING bind_argument[,......]]

}

  如 :

  IF NOT xscur%ISOPEN THEN

            OPEN xscur FOR SELECT * FROM xs;

  END IF ;

游标变量同样可以使用游标属性 :%FOUND,%ISOPEN,%ROWTYPE

在使用过程中 , 其他的 OPEN 语句可以为不同的查询打开相同的游标变量 . 因此 , 在重新打开之前 , 不要关闭游标变量 . 可以打开游标 , 并作为参数传递给存储过程 . 如 :

CREATE PACKAGE xs_data AS

...

TYPE xs_cur IS REF CURSOR RETURN xs%ROWTYPE;

RROCEDURE open_xs(xscur IN OUT xs_cur);

END xs_data;

 

CREATE PACKAGE BODY xs_data AS

...

PROCEDURE open_xs(xscur IN OUT xs_cur)

AS

BEGIN

      OPEN xscur FOR SELECT * FROM xs;

END open_xs;

END xs_data;

当声明一个游标变量作为打开游标变量子程序的参数时 , 必须定义 IN OUT 模式 . 也就是说 , 子程序可以将一个打开的游标变量传递给调用者 .
分享到:
评论

相关推荐

    oracle游标变量和数据包

    根据提供的文件内容,本文将详细解释Oracle中的游标变量与程序包的概念及其应用。 ### 一、游标变量 #### 1. Refcursor 类型创建 在 Oracle 的 PL/SQL 环境中,Refcursor 是一种特殊的游标类型,它可以作为函数的...

    游标和异常处理 游标和异常处理

    在实际应用中,显式游标可以用于处理多行数据的查询结果,例如查询员工表中的所有数据,并将其存储在游标变量中,然后应用程序再从游标变量中分解出需要的数据,并进行处理。 异常处理是数据库系统中非常重要的一...

    ORACLE 游标使用示例

    在"游标.txt"文件中,可能包含了更多关于Oracle游标的使用实例和技巧,包括游标的声明、动态游标、游标变量、游标表达式以及游标在存储过程和函数中的应用。这些内容可以帮助你更深入地理解和掌握Oracle游标,提高你...

    Mysql游标(循环操作)

    3. **获取数据**:通过`FETCH`命令从游标中获取一行数据到声明的变量中。 4. **处理数据**:在获取数据后,可以根据实际需求对数据进行各种处理。 5. **关闭游标**:使用完毕后,需要使用`CLOSE`命令关闭游标,释放...

    oracle 隐式游标,显示游标,游标循环

    - `FETCH`语句用于从游标中获取数据,并将其存储到变量`v_employee`中。 - 使用`c_employees%NOTFOUND`来判断是否还有数据可取。 ##### 5. 关闭游标 ```sql CLOSE c_employees; ``` #### 四、游标循环 游标循环是...

    使用表变量而不是游标变量

    我将在这里解释如何使用表变量以及克服游标限制

    Oracle游标使用案例大全

    - 游标变量:是一种特殊的PL/SQL变量,可以存储游标对象,便于在不同的PL/SQL块间传递游标状态。 9. **游标函数** - 游标函数:返回一个游标类型的函数,可以作为其他PL/SQL块的输入,使得游标可以在多个层次的...

    oracle 游标 深入浅出 详解 精析 示例

    游标变量的使用与显式游标类似,但无需定义游标,而是直接打开和关闭变量。 游标在PL/SQL中扮演着至关重要的角色,提供了处理复杂数据流和交互的强大工具。了解并熟练掌握游标的使用,对于编写高效、灵活的数据库...

    SQL游标使用金典

    3. **提取数据**(`FETCH`):从游标中获取一行数据,并将其存储到变量中。 4. **关闭游标**(`CLOSE`):释放游标当前持有的数据,但不销毁游标本身。 5. **释放游标**(`DEALLOCATE`):彻底销毁游标,释放其占用...

    SQL Server遍历表中记录的2种方法(使用表变量和游标)

    本文将深入探讨两种方法:使用表变量和使用游标。 首先,我们来看如何通过表变量来遍历记录。表变量在SQL Server中是一种临时存储数据的结构,它与临时表相似但作用范围更小,仅限于当前批处理或存储过程。以下是一...

    游标例题 获取游标中的某一行

    在大多数数据库系统中,声明游标涉及定义一个游标变量并指定一个SQL查询。例如,在PL/SQL(Oracle的编程语言)中,声明游标可能如下所示: ```sql DECLARE my_cursor CURSOR FOR SELECT column1, column2 FROM ...

    oracle数据库的游标

    显式游标需要开发者明确声明、打开、获取数据以及关闭。在使用显式游标时,通常通过循环结构来迭代游标中的数据。游标循环有多种实现方式,包括使用loop循环、while循环和for循环。每种循环方式有其特定的场景和优势...

    解析数据库中游标的使用方法

    游标一旦打开,数据就从数据库中传送到游标变量中,然后应用程序再从游标变量中分解出需要的数据,并进行处理。以下将通过详细的例子为您介绍显式游标和隐式游标。 显式游标: 1. 定义游标:CURSOR CUR_NAME P1,P2...

    SQL Server 游标用法

    1. **声明(DECLARE)**:声明游标时,我们需要指定游标的名称、游标的类型(如静态、动态、快照等),以及游标将基于的SQL查询。例如: ```sql DECLARE my_cursor1 CURSOR FOR SELECT rowid, title FROM tempTab...

    oracle游标使用大全

    这个游标有三个主要属性:SQL%FOUND, SQL%NOTFOUND和SQL%ROWCOUNT,用于检查查询是否成功以及处理的行数。 - 显式游标:显式游标允许我们更精细地控制查询结果,包括遍历结果集、读取当前行数据、移动到下一行等。...

    Oracle存储过程游标详解

    For 循环游标隐式打开游标,自动滚动获取一条记录,并自动创建临时记录类型变量存储记录。处理完后自动关闭游标。While 循环游标需要手动打开和关闭游标,并使用 Fetch 语句获取记录。 在实际应用中,游标可以用于...

    Oracle 游标使用大全

    - 可以声明并使用游标变量来存储游标状态,方便在PL/SQL块中传递和操作。 4. **游标循环处理** - 在PL/SQL中,经常用FOR循环处理游标,简化代码,提高可读性。 5. **游标属性** - %FOUND:检查是否从游标中成功...

    非常详细的Oracle游标整理

    - 显式游标声明包含游标变量和关联的SQL查询,例如`cursor rowList is select * from chg_test_b b;` - 显式游标有四个关键状态:打开(Open)、关闭(Close)、获取(Fetch)和定位(Fetch into)。 - 在循环中...

    Oracle数据库的游标学习总结

    接着,我们定义了一个游标变量`carec`,它的类型与游标`ca`返回的行类型相同。通过`FOR`循环,我们可以遍历查询结果并打印出每个员工的名字。 除了使用`FOR`循环,我们还可以使用`LOOP`循环来访问游标。这种方式...

Global site tag (gtag.js) - Google Analytics