zoukankan      html  css  js  c++  java
  • SQL Server 2005游标

    SQL Server 2005游标

    Fromhttp://hi.baidu.com/liangzirenshen/blog/item/07c3ead12351e687a1ec9c25.html

    5,职工普调工资,从最低工资调起,每人工资长10%,但工资总额不能超过50万元。当调完某个职工工资后,如果工资总额达到或超过50万元,就不再调了,另外,如果职工全部调了一遍,工资总额还没到50万元,也到此为止。现有职工表emp,定义了一个游标cl,游标的查询语句取出职工号和工资值,并按增序排列。下面是程序代码:

    void addsalary()

    { EXEC SQL BEGIN DECLARE SECTION //声明SQL变量//

    char empno[8], e_snoSQLSTATE[6]

    float s_sal, e_sal

    EXEC SQL END DECLARE SECTION; //声明SQL变量完//

    EXEC SQL DECLARE cl CURSOR FOR //定义游标 cl ,emp表的eno,sal列可以作任何操作

    SELECT eno, sal

    FROM emp

    ORDER BY sal ASC;

    EXEC SQL OPEN cl; //打开游标/

    EXEC SQL SELECT SUM(sal) INTO @s_sal FROM emp; //取工资总和到s_sal

    while(s_sal < 500000.00)

    {

    EXEC SQL FETCH FROM cl

    INTO @e_sno , @e_sal; //从游标中读出的数据放入e_sno,e_sal变量

    If(SQLSTATE='02000') BREAK; //读完记录,退出//

    EXEC SQL UPDATE emp

    SET sal=sal*1.1 //游标内容更新,将empno=e_sno相应的sal*1.1

    WHERE empno=@e_eno;

    s_sal = s_sal+ e_sal *0.1; //计算工资总和到s_sal

    };

    EXEC SQL CLOSE cl; /关闭游标/}

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

    当你需要对select出来的结果循环处理的时候就需要用到游标。

    如下面的一个存储过程中就用了一个游标:

    Create Proc Pr_DeleteTable

    as

    declare @Table varchar(20)

    declare cr_cursor cursor --1.定义游标

    for select name from dbo.sysobjects where xtype='U' and status>0

    open cr_cursor --2.打开游标

    fetch From cr_cursor into @Table --3.提取游标

    while @@fetch_status=0

    begin

    print @Table --执行打印操作

    fetch next From cr_cursor into @Table

    end;

    close cr_cursor --4.关闭游标

    deallocate cr_cursor --5.释放游标

    ================================

    1. 定义游标定义

    游标语句的核心是定义了一个游标标识名,并把游标标识名和一个查询语句关联起来。DECLARE语句用于声明游标,它通过SELECT查询定义游标存储的数据集合。语句格式为:

    DECLARE 游标名称 [INSENSITIVE] [SCROLL]

    CURSOR FOR select语句

    [FOR{READ ONLY|UPDATE[OF 列名字表]}]

    参数说明:

    INSENSITIVE选项:说明所定义的游标使用SELECT语句查询结果的拷贝,对游标的操作都基于该拷贝进行。因此,这期间对游标基本表的数据修改不能反映到游标中。这种游标也不允许通过它修改基本表的数据。

    SCROLL选项:指定该游标可用所有的游标数据定位方法提取数据,游标定位方法包括PRIORFIRSTLASTABSOLUTE n RELATIVE n 选项。

    Select语句:为标准的SELECT查询语句,其查询结果为游标的数据集合,构成游标数据集合的一个或多个表称作游标的基表。

    在游标声明语句中,有下列条件之一时,系统自动把游标定义为INSENSITIVE游标:

    SELECT语句中使用了DISTINCTUNION GROUP BYHAVING等关键字;

    任一个游标基表中不存在唯一索引。

    其他

    READ ONLY选项:说明定义只读游标。

    UPDATE [OF 列名字表]选项:定义游标可修改的列。如果使用OF 列名字表选项,说明只允许修改所指定的列,否则,所有列均可修改。

    例如,查询教师名字和所教的课程名,定义游标TCURSOR的语句如下

    DECLARE TCURSOR CURSOR FOR

    SELECT tname, cname

    FROM teacher ,couse

    WHERE teacher.tno = couse.tno

    2. 打开游标

    打开游标语句执行游标定义中的查询语句,查询结果存放在游标缓冲区中。并使游标指针指向游标区中的第一个元组,作为游标的缺省访问位置。查询结果的内容取决与查询语句的设置和查询条件。

    打开游标的语句格式:

    EXEC SQL OPEN 〈游标名〉

    如果打开的游标为INSENSITIVE游标,在打开时将产生一个临时表,将定义的游标数据集合从其基表中拷贝过来。

    SQL Server,游标打开后,可以从全局变量@@CURSOR_ROWS中读取游标结果集合中的行数。

    1:打开前面所创建的查询教师姓名和所教课名称的游标。

    OPEN tcursor

    2:显示游标结果集合中数据行数

    SELECT 数据行数 = @@CURSOR_ROWS

    3. 读游标区中的当前元组

    读游标区数据语句是读取游标区中当前元组的值,并将各分量依次赋给指定的共享主变量。FETCH语句用于读取游标中的数据,语句格式为:

    FETCH [[NEXT|PRIOR|FIRST|LAST| ABSOLUTE n| RELATIVE n]

    FROM ] 游标名

    [INTO @变量1, @变量2, .]

    其中:

    NEXT:说明读取游标中的下一行,第一次对游标实行读取操作时,NEXT返回结果集合中的第一行。

    PRIORFIRSTLASTABSOLUTE n RELATIVE n 选项只适用于SCROLL游标。它们分别说明读取游标中的上一行、第一行、最后一行、第n 行和相对于当前位置的第n 行。n 为负值时,ABSOLUTE n RELATIVE n 说明读取从游标结果集合中的最后一行或当前行倒数n行的数据。

    INTO子句 说明将读取的数据存放到指定的局部变量中,每一个变量的数据类型应与游标所返回的数据类型严格匹配,否则将产生错误。

    如果游标区的元组已经读完,那么系统状态变量SQLSTATE的值被设为02000,意为"no tuple found"

    例如,读取tcursor中当前位置后的第二行数据

    FETCH RELATIVE 2 FROM tcursor

    4. 利用游标修改数据

    SQL Server中的 UPDATE语句 DELETE语句也支持游标操作,它们可以通过游标修改或删除游标基表中的当前数据行。

    UPDATE语句的格式为:

    UPDATE table_name

    SET 列名=表达式}[,n]

    WHERE CURRENT OF cursor_name

    DELETE语句的格式为:

    DELETE FROM table_name

    WHERE CURRENT OF cursor_name

    说明:

    CURRENT OF cursor_name

    表示当前游标指针所指的当前行数据。CURRENT OF 只能在UPDATEDELETE语句中使用。

    注意:

    o使用游标修改基表数据的前提是声明的游标是可更新的。

    o 对相应的数据库对象(游标的基表)有修改和删除权限。

    5. 关闭游标

    关闭游标后,游标区的数据不可再读。CLOSE语句关闭已打开的游标,之后不能对游标进行读取等操作,但可以使用OPEN语句再次打开该游标。

    CLOSE语句的格式为:

    CLOSE 游标名

    例如:关闭tcursor游标如下描述:

    CLOSE tcursor

    6 删除游标语句

    DEALLOCATE语句删除定义游标的数据结构,删除后不可再用。语句格式:

    DEALLOCATE 游标名

    例如,删除tcursor游标

    DEALLOCATE tcursor

    1,JS2001班的学生的学号和姓名:

    #define MAX 30

    EXEC SQL BEGIN DECLARE SECTION;

    char TN[12], FU[20] //定义主变量//

    EXEC SQL END DECLARE SECTION;

    char tarn1[30][12],tarn2[30][20] //定义 C 变量//

    . . . . . .

    EXEC SQL //执行SQL语句,定义游标//

    DCLARE Scursor CURSOR FOR //声明游标Scursor//

    SELECT sno,sname //查询sno,sname//

    FROM student //studentchax 查询//

    WHERE sclass = 'JS2001' //sclass'JS2001'的班级//

    EXEC SQL OPEN Scursor //打开游标//

    for (i=0; i<MAX; i++)

    { EXEC SQL FETCH FROM Scursor

    INTO @TN, @FU //取到宿主变量//

    tarn1= TN; //赋值到C数组变量//

    tarn2= FU;

    }

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

    EXEC SQL CLOSE Scursor //关闭游标//

    EXEC SQL DEALLOCATE Scursor //删除游标//

    2,定义游标,使结果集包括 pubs 数据库的 authors 表中的所有行和列。因为没指定 SCROLL 选项,FETCH NEXT 是唯一可用的提取选项。

    DECLARE authors_cursor CURSOR FOR //声明游标authors_cursor //

    SELECT * FROM authors

    OPEN authors_cursor //打开游标authors_cursor //

    FETCH NEXT FROM authors_cursor //读游标authors_cursor中的一行 //

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

    3, 定义和使用滚动游标

    DECLARE tcursor SCROLL CURSOR FOR

    SELECT tname, cname FROM teacher ,couse

    WHERE teacher.tno = couse.tno;

    OPEN tcursor;

    tcursor中当前位置向下的第二行数据

    FETCH RELATIVE 2 FROM tcursor

    tcursor中最后一行数据

    FETCH LAST FROM tcursor

    tcursor中当前位置向前的第4行数据

    FETCH RELATIVE -4 FROM tcursor

    4 利用 @@FETCH_STATUS 控制一个 WHILE 循环中的游标活动。

    DECLARE S_Cursor CURSOR FOR

    SELECT sname, sno FROM student

    OPEN S_Cursor

    FETCH NEXT FROM S_Cursor

    WHILE @@FETCH_STATUS = '000000'

    BEGIN FETCH NEXT FROM S_Cursor END

    CLOSE S_Cursor

    DEALLOCATE S_Cursor

    5,职工普调工资,从最低工资调起,每人工资长10%,但工资总额不能超过50万元。当调完某个职工工资后,如果工资总额达到或超过50万元,就不再调了,另外,如果职工全部调了一遍,工资总额还没到50万元,也到此为止。现有职工表emp,定义了一个游标cl,游标的查询语句取出职工号和工资值,并按增序排列。下面是程序代码:

    void addsalary()

    { EXEC SQL BEGIN DECLARE SECTION //声明SQL变量//

    char empno[8], e_snoSQLSTATE[6]

    float s_sal, e_sal

    EXEC SQL END DECLARE SECTION; //声明SQL变量完//

    EXEC SQL DECLARE cl CURSOR FOR //定义游标 cl ,emp表的eno,sal列可以作任何操作

    SELECT eno, sal

    FROM emp

    ORDER BY sal ASC;

    EXEC SQL OPEN cl; //打开游标/

    EXEC SQL SELECT SUM(sal) INTO @s_sal FROM emp; //取工资总和到s_sal

    while(s_sal < 500000.00)

    {

    EXEC SQL FETCH FROM cl

    INTO @e_sno , @e_sal; //从游标中读出的数据放入e_sno,e_sal变量

    If(SQLSTATE='02000') BREAK; //读完记录,退出//

    EXEC SQL UPDATE emp

    SET sal=sal*1.1 //游标内容更新,将empno=e_sno相应的sal*1.1

    WHERE empno=@e_eno;

    s_sal = s_sal+ e_sal *0.1; //计算工资总和到s_sal

    };

    EXEC SQL CLOSE cl; /关闭游标/}

    SQL Server提供两种游标应用接口方法:第一种是符合ANSI标准的SQL游标语句,它们可以实现声明、打开、读取或关闭游标操作,这些语句可用在Transact_SQL语句或存储过程内;第二种是库函数形式,客户端的DB_Library ODBC应用程序可以调用这些函数。

    游标语句增强了Transact_SQL对集合数据的处理能力,在SQL Server中,通过游标还可以修改或删除基表中的数据。

    7,使用游标时应注意的问题:

    (1) 尽管使用游标比较灵活,可以实现对数据集中单行数据的直接操作,但游标会在下面几个方面影响系统的性能:

    -使用游标会导致页锁与表锁的增加

    -导致网络通信量的增加

    -增加了服务器处理相应指令的额外开销

    (2) 使用游标时的优化问题:

    -明确指出游标的用途:for read onlyfor update

    -for update后指定被修改的列

    动态游标的意思是说任何影响结果数据集的修改都将被反映出来。也就是说,游标的结果集中的数据 同数据库中的数据会同步地改变。通俗一点就是说你当开了游标后,但数据库的数据有所改变,你在滚动的时候游标都能检测到,并反应在结果集中,所以他的结果集会一边滚动一边随着数据改变.

    也是基于这个原因,动态游标结果集中的行数据值、顺序和成员在每次提取时都会改变,不能使用ABSOLUTE方式来提取结果集中特定行的记录。

  • 相关阅读:
    过去式和过去进行式
    现在式和现在进行式
    英文文法的最基本规则
    Vue 标签中的ref属性和refs
    APICloud
    小程序
    React 传值 组件传值 之间的关系
    css clip样式 属性功能及作用
    小程序点击预览 为什么显示空白
    小程序
  • 原文地址:https://www.cnblogs.com/stublue/p/1793312.html
Copyright © 2011-2022 走看看