如何实现依次读取游标中各行数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现依次读取游标中各行数据相关的知识,希望对你有一定的参考价值。

一篇很不错的关于游标学习的文章复制给你看
在这一步中,需要指定游标的属性和根据要求产生的结果集。有两种方法可以指定一个游标。

  形式1(ANSI 92)

DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR READ ONLY | UPDATE ][OF column_list]]
  形式2

DECLARE cursor_name CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
FOR select_statement
[FOR READ ONLY | UPDATE ][OF column_list]]
INSENSITIVE关键字指明要为检索到的结果集建立一个临时拷贝,以后的数据从这个临时拷贝中获取。如果在后来游标处理的过程中,原有基表中数据发生了改变,那么它们对于该游标而言是不可见的。这种不敏感的游标不允许数据更改。

  SCROLL关键字指明游标可以在任意方向上滚动。所有的fetch选项(first、last、next、relative、absolute)都可以在游标中使用。如果忽略该选项,则游标只能向前滚动(next)。

  Select_statement指明SQL语句建立的结果集。Transact SQL语句COMPUTE、COMPUTE BY、FOR BROWSE和INTO在游标声明的选择语句中不允许使用。

  READ ONLY指明在游标结果集中不允许进行数据修改。

  UPDATE关键字指明游标的结果集可以修改。

  OF column_list指明结果集中可以进行修改的列。缺省情况下(使用UPDATE关键字),所有的列都可进行修改。

  LOCAL关键字指明游标是局部的,它只能在它所声明的过程中使用。

  GLOBAL关键字使得游标对于整个连接全局可见。全局的游标在连接激活的任何时候都是可用的。只有当连接结束时,游标才不再可用。
FORWARD_ONLY指明游标只能向前滚动。

  STATIC的游标与INSENSITIVE的游标是相同的。

  KEYSET指明选取的行的顺序。SQL Server将从结果集中创建一个临时关键字集。如果对数据库的非关键字列进行了修改,则它们对游标是可见的。因为是固定的关键字集合,所以对关键字列进行修改或新插入列是不可见的。

  DYNAMIC指明游标将反映所有对结果集的修改。

  SCROLL_LOCK是为了保证游标操作的成功,而对修改或删除加锁。

  OPTIMISTIC指明哪些通过游标进行的修改或者删除将不会成功。

  注意:

  · 如果在SELECT语句中使用了DISTINCT、UNION、GROUP BY语句,且在选择中包含了聚合表达式,则游标自动为INSENSITIVE的游标。

  · 如果基表没有唯一的索引,则游标创建成INSENSITIVE的游标。

  · 如果SELECT语句包含了ORDER BY,而被ORDER BY的列并非唯一的行标识,则DYNAMIC游标将转换成KEYSET游标。如果KEYSET游标不能打开,则将转换成INSENSITIVE游标。使用SQL ANSI-92语法定义的游标同样如此,只是没有INSENSITIVE关键字而已。

  ii. 打开游标

  打开游标就是创建结果集。游标通过DECLARE语句定义,但其实际的执行是通过OPEN语句。语法如下:

  OPEN [GLOBAL] cursor_name | cursor_variable_name
  GLOBAL指明一个全局游标。

  Cursor_name是被打开的游标的名称。

  Cursor_variable_name是所引用游标的变量名。该变量应该为游标类型。

  在游标被打开之后,系统变量@@cursor_rows可以用来检测结果集的行数。@@cursor_rows为负数时,表示游标正在被异步迁移,其绝对值(如果@@cursor_rows为-5,则绝对值为5)为当前结果集的行数。异步游标使用户在游标被完全迁移时仍然能够访问游标的结果。

  iii. 从游标中取值

在从游标中取值的过程中,可以在结果集中的每一行上来回移动和处理。如果游标定义成了可滚动的(在声明时使用SCROLL关键字),则任何时候都可取出结果集中的任意行。对于非滚动的游标,只能对当前行的下一行实施取操作。结果集可以取到局部变量中。Fetch命令的语法如下:

FETCH [NEXT | PRIOR| FIRST | LAST | ABSOLUTE n | @nvar | RELATIVE n | @nvar]
FROM [GLOBAL] cursor_name | cursor_variable_name
[INTO @variable_name ][,……n]]
NEXT指明从当前行的下一行取值。

  PRIOR指明从当前行的前一行取值。

  FIRST是结果集的第一行。

  LAST是结果集的最后一行。

  ABSOLUTE n表示结果集中的第n行,该行数同样可以通过一个局部变量传播。行号从0开始,所以n为0时不能得到任何行。

  RELATIVE n表示要取出的行在当前行的前n行或后n行的位置上。如果该值为正数,则要取出的行在当前行前n行的位置上,如果该值为负数,则返回当前行的后n行。

  INTO @cursor_variable_name表示游标列值存储的地方的变量列表。该列表中的变量数应该与DECLARE语句中选择语句所使用的变量数相同。变量的数据类型也应该与被选择列的数据类型相同。直到下一次使用FETCH语句之前,变量中的值都会一直保持。

  每一次FETCH的执行都存储在系统变量@@fetch_status中。如果FETCH成功,则@@fetch_status被设置成0。@@fetch_status为-1表示已经到达了结果集的一部分(例如,在游标被打开之后,基表中的行被删除)。@@fetch_status可以用来构造游标处理的循环。

  例如:

DECLARE @iname char(20), @fname char(20)
OPEN author_cur
FETCH FIRST FROM author_cur INTO @iname, @fname
WHILE @@fetch_status = 0
BEGIN
IF @fname = ‘Albert’
PRINT “Found Albert Ringer”
ELSE
Print “Other Ringer”
FETCH NEXT FROM author_cur INTO @iname, @fname
END
  iv. 关闭游标

  CLOSE语句用来关闭游标并释放结果集。游标关闭之后,不能再执行FETCH操作。如果还需要使用FETCH语句,则要重新打开游标。语法如下:

  CLOSE [GLOBAL] cursor_name | cursor_variable_name
  v. 释放游标

  游标使用不再需要之后,要释放游标。DEALLOCATE语句释放数据结构和游标所加的锁。语法如下:

  DEALLOCATE [GLOBAL] cursor_name | cursor_variable_name
  下面给出游标的一个完整的例子:

  USE master
  GO
  CREATE PROCEDURE sp_BuildIndexes
  AS
  DECLARE @TableName sysname, @msg varchar(100), @cmd varchar(100)
  DECLARE table_cur CURSOR FOR
  SELECT name FROM sysobjects WHERE type=’u’
  OPEN table_cur
  FETCH NEXT FROM table_cur INTO @TableName
  WHILE @@fetch_status = 0
  BEGIN
  IF @@fetch_status = -2
  CONTINUE
  SELECT @msg = “Building indexes for table”+@TableName+”…”
  PRINT @msg
  SELECT @cmd = “DBCC DBREINDEX (‘”+@TableName+”')”
  EXEC (@cmd)
  PRINT “ “
  FETCH NEXT FROM table_cur INTO @TableName
  END
  DEALLOCATE table_cur
  GO
  下面的脚本将为PUBS数据库执行sp_BuildIndexes

  USE pubs
  GO
  EXEC ap_BuildIndexes
参考技术A 偏右宫角位置

如何实现Oracle数据库中的动态游标

    create or replace procedure P_TEST_SQL is    

    TYPE ref_cursor_type IS REF CURSOR;  --定义一个动态游标     

    tablename varchar2(200) default \'ess_client\';    

    v_sql varchar2(1000);    

    mobile varchar2(15);    

    usrs ref_cursor_type;    

    begin    

    --使用连接符拼接成一条完整SQL     

    v_sql := \'select usrmsisdn from \'||tablename||\' where rownum < 11\';    

    --打开游标     

    open usrs for v_sql ;    

    loop    

    fetch usrs into mobile;     

    exit when usrs%notfound;    

    insert into tmp(usrmsisdn) values(mobile);    

    end loop;    

    close usrs;    

    commit;    

    end P_TEST_SQL;  

参考技术A declare --类型定义 cursor c_job is select empno,ename,job,sal from emp where job='MANAGER'; --定义一个游标变量v_cinfo c_emp%ROWTYPE ,该类型为游标c_emp中的一行数据类型 c_row c_job%rowtype;begin for c_row in c_job loop dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal); end loop;end; 参考技术B For 循环游标
(1)定义游标
(2)定义游标变量
(3)使用for循环来使用这个游标declare --类型定义 cursor c_job is select empno,ename,job,sal from emp where job='MANAGER'; --定义一个游标变量v_cinfo c_emp%ROWTYPE ,该类型为游标c_emp中的一行数据类型 c_row c_job%rowtype;begin for c_row in c_job loop dbms_output.put_line(c_row.empno||'-'||c_row.ename||'-'||c_row.job||'-'||c_row.sal); end loop;end;

以上是关于如何实现依次读取游标中各行数据的主要内容,如果未能解决你的问题,请参考以下文章

如何实现Oracle数据库中的动态游标

sql server 中游标详解

SQL server2014数据库存储过程 实现游标循环读取 循环插入数据

Solr中如何使用游标进行深度分页查询

如何在 PL / SQL 中读取另一个游标内的游标

如何在android中使用游标(sqlite查询)搜索数据库