• SQL——游标


    非原创—东拼西凑来的

    游标(cursor)是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。

    游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改。不像多数DBMS,MySQL游标只能用于存储过程(和函数)。

    简单的说,游标(CURSOR)的特殊性在于它可以用循环对返回值进行逐条编译,它具有只读性、不可跳跃性和迟钝性。

    游标会吃更多的内存,减少可用的并发。

    游标5个组成部分

    1、声明 2、打开 3、从游标中查找信息 4、关闭 5、释放

    在能够使用游标前,必须声明(定义)它。这个过程实际上没有检索数据,它只是定义要使用的SELECT语句:

    DECLARE 游标名 CURSOR
    FOR
    SELECT 语句 #此处必须是SELECT语句
    
    • 1
    • 2
    • 3

    一旦声明后,必须打开游标以供使用。这个过程用前面定义的SELECT语句把数据实际检索出来:

    OPEN 游标名;
    
    • 1

    对于填有数据的游标,根据需要取出(检索)各行:

    FETCH... FROM 游标名
    
    • 1

    FETCH指定检索什么数据,即所需的列,并指定检索出来的数据存储在什么地方。它还向前移动游标中的内部行指针,使下一条FETCH语句检索下一行,以不重复读取同一行。

    在结束游标使用时,必须关闭游标:

    CLOSE 游标名;
    
    • 1

    在声明游标后,可根据需要频繁地打开和关闭游标。在游标打开后,可根据需要频繁地执行取操作。

    游标创建

    游标用DECLARE语句创建。DECLARE命名游标,并定义相应的SELECT语句,根据需要带WHERE和其他子句。

    CREATE PROCEDURE 储存过程名()
    BEGIN
    DECLARE 游标名 CURSOR
    FOR
    SELECT...
    FROM...
    WHERE...
    END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    存储过程处理完成后,游标就“消失”了(因为它局限于存储过程之中)。

    创建打开关闭游标举例

    如前文所述,在定义游标之后,可以打开它:

    declare cursor1(游标名) cursor for select XXX--声明游标 1
    open XXXX--打开 2
    fetch next from XXX into XXX--将游标值赋给XXX   3
    while(@@fetch_status=0)--循环查找
    fetch next from XXX into XXX--同上
    close cursor1--关闭游标   4
    deallocate cursor1--解散游标   5
    ?
    fetch_status
    0 FETCH 语句成功
    -1 FETCH 语句失败或此行不在结果集中
    -2 被提取的行不存在
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    CLOSE释放游标使用的所有内部内存和资源,因此在每个游标不再需要时都应该关闭。

    在一个游标关闭后,如果没有重新打开,则不能使用它。但是,使用声明过的游标不需要再次声明,用OPEN语句打开它就可以了。

    使用游标举例

    在我们打开了游标后,如前文所述,可以用FETCH语句分别访问它的每一行:

    alter PROCEDURE cursor_a_b_insert
    @aId int,
    @aName nchar(10)
    AS
    
    declare @id int
    declare @name varchar(50)
    
    declare cursor1 cursor for         --定义游标cursor1
    select bid,bname from b where aid=@aId             --使用游标的对象(跟据需要填入select文)
    open cursor1                       --打开游标
    fetch next from cursor1 into @id,@name  --将游标向下移1行,获取的数据放入之前定义的变量@id,@name中
    while @@fetch_status=0           --判断是否成功获取数据
    begin
    update b set bname=@aName+'1' where bid=@id                           --进行相应处理(跟据需要填入SQL文)
    update a set aname=@aName where aid=@aId
    fetch next from cursor1 into @id,@name  --将游标向下移1行
    end
    close cursor1                   --关闭游标
    deallocate cursor1 
    
    
    exec cursor_a_b_insert 55,'王媛媛'
    
    
    
    
    
    alter proc cursor_pr_UpUser
    @NoteUserId int
    as
    begin transaction
    declare @NLId int
    declare @NPLId int
    --创建用户所对应的日志游标cursorNLId,将日志id放入@NLId游标中
    declare cursorNLId cursor for select NoteLogId from NoteLogs where NUId=@NoteUserId
    open cursorNLId
    fetch next from cursorNLId into @NLId
    
    while @@fetch_status=0 --判断是否成功获取数据
    begin
    --创建日志所对应的评论游标cursorNPLId,将评论id放入@NPLId游标中
    declare cursorNPLId cursor for select NotePingLunId from NotePingLun where NLId=@NLId
    open cursorNPLId
    fetch next from cursorNPLId into @NPLId
    while @@fetch_status=0
    begin
    --根据评论游标@NPLId修改评论状态
    update dbo.NoteReply set NoteDel=0 where NoteReplyId=@NPLId
    fetch next from cursorNPLId into @NPLId
    end
    --当评论游标遍历完关闭
    close cursorNPLId --关闭游标
    deallocate cursorNPLId
    --根据日志游标@NPLId修改日志状态
    update dbo.NotePingLun set NoteDel=0 where NLId=@NLId
    fetch next from cursorNLId into @NLId
    
    end
    --关闭日志游标
    close cursorNLId --关闭游标
    deallocate cursorNLId
    --根据用户修改用户和日志状态
    update dbo.NoteUser set NoteDel=0 where NoteuserId=@NoteUserId
    update dbo.NoteLogs set NoteDel='qq' where NUId=@NoteUserId
    if @@error<>0 --如果有错误
    begin
    print '删除失败,回滚事务'
    rollback transaction --回滚
    end
    else
    begin
    print '删除成功,提交事务'
    commit transaction
    end
    go
    
    exec cursor_pr_UpUser 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    其中FETCH语句自动从第一行开始检索当前行的order_num列,并存储到一个名为“乖巧的局部变量”的局部声明的变量中。

    最后

    深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

    因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

    小编已加密:aHR0cHM6Ly9kb2NzLnFxLmNvbS9kb2MvRFVrVm9aSGxQZUVsTlkwUnc==出于安全原因,我们把网站通过base64编码了,大家可以通过base64解码把网址获取下来。

  • 相关阅读:
    springboot保险公司车辆事故跟踪管理系统011444
    day30 SQL注入&CTF&二次&堆叠&DNS带外
    【图神经网络论文整理】(一)—— 可解释性和泛化性图分类的因果注意力:CAL
    Centos下使用containerd管理容器:5分钟从docker转型到containerd
    【Linux】Linux的常见指令详解(上)
    【无标题】
    多年没有这么花时间解决一个问题了
    vue中动态引入图片
    对于xshell连接不上虚拟机的一些解答
    【***二叉树***】
  • 原文地址:https://blog.csdn.net/web15286201346/article/details/126812200