zoukankan      html  css  js  c++  java
  • SQL CURSOR 游标 存储过程

    /*
    原理:游标就是把数据按照指定要求提取出相应的数据集,然后逐条进行数据处理。
    1.1游标的概念
      游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集。
     使用游标(cursor)的一个主要的原因就是把集合操作转换成单个记录处理方式。
     用SQL语言从数据库中检索数据后,结果放在内存的一块区域中,且结果往往是一个含有多个记录的集合。
     游标机制允许用户在SQL server内逐行地访问这些记录,按照用户自己的意愿来显示和处理这些记录。
    1.2 游标的优点
    从游标定义可以得到游标的如下优点,这些优点使游标在实际应用中发挥了重要作用:
       1)允许程序对由查询语句select返回的行集合中的每一行执行相同或不同的操作,而不是对整个行集合执行同一个操作。
       2)提供对基于游标位置的表中的行进行删除和更新的能力。
       3)游标实际上作为面向集合的数据库管理系统(RDBMS)和面向行的程序设计之间的桥梁,使这两种处理方式通过游标沟通起来。

    1.3 游标的使用
     讲了这个多游标的优点,现在我们就亲自来揭开游标的神秘的面纱。
     使用游标的顺序: 声名游标、打开游标、读取数据、关闭游标、删除游标。
    1.3.1声明游标
     最简单游标声明:DECLARE <游标名>CURSOR FOR<SELECT语句>;
     其中select语句可以是简单查询,也可以是复杂的接连查询和嵌套查询
    1.3.2 打开游标
     非常简单,我们就打开刚才我们声明的游标mycursor
     OPEN mycursor
    1.3.3读取数据
      FETCH [ NEXT | PRIOR | FIRST | LAST] FROM { 游标名 | @游标变量名 } [ INTO @变量名 [,…] ] 
      参数说明:
      NEXT   取下一行的数据,并把下一行作为当前行(递增)。
     由于打开游标后,行指针是指向该游标第1行之前,所以第一次执行FETCH NEXT操作将取得游标集中的第1行数据。
     NEXT为默认的游标提取选项。 
      INTO @变量名[,…] 把提取操作的列数据放到局部变量中。
     列表中的各个变量从左到右与游标结果集中的相应列相关联。
     各变量的数据类型必须与相应的结果列的数据类型匹配或是结果列数据类型所支持的隐性转换。
     变量的数目必须与游标选择列表中的列的数目一致。  

    1.3.4关闭游标
     CLOSE mycursor
    1.3.5删除游标 
    DEALLOCATE mycursor 

    给出具体的例子: 
    */

    ----------------------------------------------
    declare @ID nvarchar(20); --定义变量来保存ID号
    declare @DATE DATETIME;  
    DECLARE @DFD NVARCHAR(200);          --定义变量来保存值
    SET @DFD='';
    declare mycursor cursor for 
    select MID,CreatedDate from FD_Menu   --为所获得的数据集指定游标
    open mycursor    --打开游标
    fetch next from mycursor into @ID,@DATE   --开始抓第一条数据
    while(@@fetch_status=0)     --如果数据集里一直有数据
    begin
    --select tb_b.name,(tb_b.gz + @A) from tb_b where tb_b.id = @id   --开始做想做的事(什么更新呀,删除呀)
    SET @DFD=@DFD+CAST(@ID AS NVARCHAR)+'.V.'+CONVERT(NVARCHAR,@DATE,111);
    select @DFD;
            fetch next from mycursor into @ID,@DATE     --跳到下一条数据
    end
    close mycursor        --关闭游标
    deallocate mycursor --删除游标

    -------------------------------------------------------------------------
    -----------------------循环示例------------------------------------------
    -------------------------------------------------------------------------
    TRUNCATE TABLE V_TEST

    DECLARE @i INT;
    SET @i=1;
    WHILE @i<1000
    BEGIN
    INSERT INTO V_TEST (V_Name,V_DESC)values('IamV'+str(@i),'Victor'+str(1000-@i))
    SET @i=@i+1
    END

    SELECT * FROM V_TEST
    -------------------------------------------------------------------------
    DECLARE @ID BIGINT;
    DECLARE @NAME NVARCHAR(50);
    DECLARE V_CURSOR CURSOR FOR(
    SELECT V_ID,V_Name FROM V_TEST WHERE RIGHT(V_NAME,2)='10'
    )
    OPEN V_CURSOR;
    FETCH NEXT FROM V_CURSOR INTO @ID,@NAME
    WHILE (@@FETCH_STATUS=0)
    BEGIN
    PRINT CAST(@ID AS NVARCHAR)+@NAME;
     FETCH NEXT FROM V_CURSOR INTO @ID,@NAME;
    END
    CLOSE V_CURSOR;
    DEALLOCATE V_CURSOR;
    -------------------------------------------------------------------------------------
    -------------------------------------------------------------------------------------
    /*
    声明 SCROLL 游标并使用其它 FETCH 选项 
    scroll表示可随意移动游标指针(否则只能向前)
    下例创建一个 SCROLL 游标,使其通过 LAST、PRIOR、RELATIVE 和 ABSOLUTE 选项支持所有滚动能力。
    */
    -------------------------------------------------------------------------------------
    -------------------------------------------------------------------------------------
    --声明局部变量
    DECLARE @ID BIGINT;
    DECLARE @NAME NVARCHAR(50);
    DECLARE  V_CURSOR SCROLL CURSOR FOR
    SELECT V_ID,V_Name FROM V_TEST;
    OPEN V_CURSOR;
    --定位到指定位置的记录
    FETCH ABSOLUTE 50 from V_CURSOR into @ID,@NAME
    select @id as id,@name as name
    --定位到当前记录相对位置记录
    FETCH RELATIVE -30 from V_CURSOR into @id,@name
    select @id as id,@name as name
    --定位到当前记录前一条
    fetch prior from V_CURSOR into @id,@name
    select @id as id,@name as name
    --定位到当前记录后一条
    fetch next from V_CURSOR into @id,@name
    select @id as id,@name as name
    --定位到首记录
    fetch first from V_CURSOR into @id,@name
    select @id as id,@name as name
    --定位到尾记录
    fetch last from V_CURSOR into @id,@name
    select @id as id,@name as name

    CLOSE V_CURSOR;
    DEALLOCATE V_CURSOR;
    -------------------------------------------------------------------------------------
    /*

    */
    -------------------------------------------------------------------------------------
    DECLARE @ID BIGINT;
    DECLARE @NAME NVARCHAR(50);
    DECLARE V_CURSOR CURSOR SCROLL FOR(
    SELECT V_ID,V_Name FROM V_TEST WHERE RIGHT(V_NAME,2)='10'
    )
    OPEN V_CURSOR;
    FETCH NEXT FROM V_CURSOR INTO @ID,@NAME

    WHILE (@@FETCH_STATUS=0)
    BEGIN
    PRINT CAST(@ID AS NVARCHAR)+@NAME;
     FETCH RELATIVE 2 FROM V_CURSOR INTO @ID,@NAME;
    END

    CLOSE V_CURSOR;
    DEALLOCATE V_CURSOR;
    -------------------------------------------------------------------------------------
    -------------------------------------------------------------------------------------
    /*
    dynamic表示可以读写游标(否则游标只读)
    UPDATE V_TEST SET V_DESC='Victor       199' WHERE CURRENT OF V_CURSOR
    */
    -------------------------------------------------------------------------------------
    -------------------------------------------------------------------------------------
    DECLARE V_CURSOR CURSOR SCROLL DYNAMIC
    /*scroll表示可随意移动游标指针(否则只能向前)
    dynamic表示可以读写游标(否则游标只读)*/
    FOR
    SELECT V_DESC FROM V_TEST WHERE CAST(RIGHT(V_DESC,3) AS INT)<200

    OPEN V_CURSOR
    DECLARE @DESC NVARCHAR(50)

    FETCH NEXT FROM V_CURSOR INTO @DESC
    WHILE(@@fetch_status=0)
    BEGIN
     PRINT 'Product Name: ' + @DESC
     FETCH NEXT FROM V_CURSOR INTO @DESC
    END

    FETCH FIRST FROM V_CURSOR INTO @DESC
    print @DESC
    update V_TEST set V_DESC='123122' WHERE CURRENT OF V_CURSOR
    /**//*delete from product where current of my_cursor */
    CLOSE V_CURSOR
    DEALLOCATE V_CURSOR
    ----------------------------------------------------------------
    SELECT * FROM V_TEST
    update V_TEST set V_DESC='Victor       199' WHERE V_ID=801
    ---------------------------------------------------------------------------
    ---------------------------------------------------------------------------
    ---------------------------------------------------------------------------
    /*
    declare my_cursor1 cursor for
    select nContentId,dtEditTime from content where datepart(month,dtEditTime)='9' and datepart(day,dtEditTime)='26'
    open my_cursor1
    declare @date sysname
    declare @nID sysname
    declare @tempDate datetime
    fetch next from my_cursor1 into @nID,@date
    while(@@fetch_status = 0)
    begin
        set @tempDate =  dateadd(day,87,@date)
        --print @tempDate
        update Content set dtEditTime=@tempDate where nContentId = @nID
        fetch next from my_cursor1 into @nID,@date
    end
    close my_cursor1
    deallocate my_cursor1

    */

    -----------------------
    DECLARE @JJ NVARCHAR(10)
    SET @JJ='12345';
    SET @JJ= RIGHT(@JJ,LEFT(@JJ,1))
    PRINT @JJ
    ----------------------

  • 相关阅读:
    【Problem】前端项目运行:Module build failed:Error Node Sass does not yet support my current environmen
    element ui源码解析 -- Pagination篇( 副:列表页进入详情页再返回后,如何保持当前页码正确 )
    vue mixins是什么及应用
    bootstrap fileinput实现限制图片上传数量及如何控制分批多次上传
    fileinput 配置项大全,从源码中翻出了很多属性,没那么多时间一一验证,特发出来给大家参考参考
    provide inject应用及和props对比
    element ui源码解析 -- input篇
    vue指令应用--实现输入框常见过滤功能
    vue项目实现导出数据到excel
    组件绑定v-model,实现最大化复用
  • 原文地址:https://www.cnblogs.com/htys/p/3640809.html
Copyright © 2011-2022 走看看