`
dwphts520
  • 浏览: 29348 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

游标是邪恶的!

 
阅读更多

此文是网络一位牛人总结。在此收藏一下。

在关系数据库中,我们对于查询的思考是面向集合的。而游标打破了这一规则,游标使得我们思考方式变为逐行进行.对于类C的开发人员来着,这样的思考方式会更加舒服。

 

       正常面向集合的思维方式是:

 

 而对于游标来说:



 

   这也是为什么游标是邪恶的,它会使开发人员变懒,懒得去想用面向集合的查询方式实现某些功能.

      同样的,在性能上,游标会吃更多的内存,减少可用的并发,占用宽带,锁定资源,当然还有更多的代码量……

      从游标对数据库的读取方式来说,不难看出游标为什么占用更多的资源,打个比方:



 

既然游标这么邪恶,为什么还要学习游标

      我个人认为存在既是合理.归结来说,学习游标原因我归纳为以下2

    1.现存系统有一些游标,我们查询必须通过游标来实现

    2.作为一个备用方式,当我们穷尽了while循环,子查询,临时表,表变量,自建函数或其他方式扔来无法实现某些查询的时候,使用游标实现.

 

T-SQL中游标的生命周期以及实现

    T-SQL中,游标的生命周期由5部分组成

1.定义一个游标

     T-SQL中,定义一个游标可以是非常简单,也可以相对复杂,取决于游标的参数.而游标的参数设置取决于你对游标原理的了解程度.

 

     游标其实可以理解成一个定义在特定数据集上的指针,我们可以控制这个指针遍历数据集,或者仅仅是指向特定的行,所以游标是定义在以Select开始的数据集上的:



 

T-SQL中的游标定义在MSDN中如下:

 

DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]

     [ FORWARD_ONLY | SCROLL ]

     [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]

     [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]

     [ TYPE_WARNING ]

     FOR select_statement

     [ FOR UPDATE [ OF column_name [ ,...n ] ] ]

[;]

    

 

 

   看起来很让人头痛是吧.下面仔细讲一下如何定义游标:

 

   游标分为游标类型和游标变量,对于游标变量来说,遵循T-SQL变量的定义方法(啥,不知道T-SQL变量定义的规则?参考我前面的博文).游标变量支持两种方式赋值,定义时赋值和先定义后赋值,定义游标变量像定义其他局部变量一样,在游标前加”@”,注意,如果定义全局的游标,只支持定义时直接赋值,并且不能在游标名称前面加“@”,两种定义方式如下:



 

下面我们来看游标定义的参数:

     LOCALGLOBAL二选一

 

     LOCAL意味着游标的生存周期只在批处理或函数或存储过程中可见,而GLOBAL意味着游标对于特定连接作为上下文,全局内有效,例如:



 

 如果不指定游标作用域,默认作用域为GLOBAL

 

     FORWARD_ONLY SCROLL 二选一

 

     FORWARD_ONLY意味着游标只能从数据集开始向数据集结束的方向读取,FETCH NEXT是唯一的选项,而SCROLL支持游标在定义的数据集中向任何方向,或任何位置移动,如下图:



 

STATIC  KEYSET  DYNAMIC  FAST_FORWARD 四选一

    这四个关键字是游标所在数据集所反应的表内数据和游标读取出的数据的关系

    STATIC意味着,当游标被建立时,将会创建FOR后面的SELECT语句所包含数据集的副本存入tempdb数据库中,任何对于底层表内数据的更改不会影响到游标的内容.

    DYNAMIC是和STATIC完全相反的选项,当底层数据库更改时,游标的内容也随之得到反映,在下一次fetch中,数据内容会随之改变

    KEYSET可以理解为介于STATICDYNAMIC的折中方案。将游标所在结果集的唯一能确定每一行的主键存入tempdb,当结果集中任何行改变或者删除时,@@FETCH_STATUS会为-2,KEYSET无法探测新加入的数据

    FAST_FORWARD可以理解成FORWARD_ONLY的优化版本.FORWARD_ONLY执行的是静态计划,而FAST_FORWARD是根据情况进行选择采用动态计划还是静态计划,大多数情况下FAST_FORWARD要比FORWARD_ONLY性能略好.

 

    READ_ONLY  SCROLL_LOCKS  OPTIMISTIC 三选一
    READ_ONLY意味着声明的游标只能读取数据,游标不能做任何更新操作

    SCROLL_LOCKS是另一种极端,将读入游标的所有数据进行锁定,防止其他程序进行更改,以确保更新的绝对成功

    OPTIMISTIC是相对比较好的一个选择,OPTIMISTIC不锁定任何数据,当需要在游标中更新数据时,如果底层表数据更新,则游标内数据更新不成功,如果,底层表数据未更新,则游标内表数据可以更新

  

 

 

2.打开游标

    当定义完游标后,游标需要打开后使用,只有简单一行代码:

OPEN test_Cursor

    注意,当全局游标和局部游标变量重名时,默认会打开局部变量游标

3.使用游标

 

   游标的使用分为两部分,一部分是操作游标在数据集内的指向,另一部分是将游标所指向的行的部分或全部内容进行操作

 

   只有支持6种移动选项,分别为到第一行(FIRST),最后一行(LAST),下一行(NEXT),上一行(PRIOR),直接跳到某行(ABSOLUTE(n)),相对于目前跳几行(RELATIVE(n)),例如:

 



 

  对于未指定SCROLL选项的游标来说,只支持NEXT取值.

    第一步操作完成后,就通过INTO关键字将这行的值传入局部变量:

 

    比如下面代码:



 

 

游标经常会和全局变量@@FETCH_STATUSWHILE循环来共同使用,以达到遍历游标所在数据集的目的,例如:

 



 

4.关闭游标

    在游标使用完之后,一定要记得关闭,只需要一行代码:CLOSE+游标名称

CLOSE test_Cursor

 

 

 

 

 

5.释放游标

    当游标不再需要被使用后,释放游标,只需要一行代码:DEALLOCATE+游标名称

DEALLOCATE test_Cursor

 

对于游标一些优化建议

<!--[if !supportLists]-->·        <!--[endif]-->     如果能不用游标,尽量不要使用游标

<!--[if !supportLists]-->·        <!--[endif]-->     用完用完之后一定要关闭和释放

<!--[if !supportLists]-->·        <!--[endif]-->     尽量不要在大量数据上定义游标

<!--[if !supportLists]-->·        <!--[endif]-->     尽量不要使用游标上更新数据

<!--[if !supportLists]-->·        <!--[endif]-->     尽量不要使用insensitive, statickeyset这些参数定义游标

<!--[if !supportLists]-->·        <!--[endif]-->     如果可以,尽量使用FAST_FORWARD关键字定义游标

 

<!--[if !supportLists]-->·        <!--[endif]-->     如果只对数据进行读取,当读取时只用到FETCH NEXT选项,则最好使用FORWARD_ONLY参数

 

 

  • 大小: 34.9 KB
  • 大小: 216.7 KB
  • 大小: 25.3 KB
  • 大小: 29 KB
  • 大小: 8.2 KB
  • 大小: 32.4 KB
  • 大小: 49.2 KB
  • 大小: 45.1 KB
  • 大小: 30.1 KB
  • 大小: 8.7 KB
  • 大小: 15.2 KB
分享到:
评论

相关推荐

    sqlserver游标的使用,游标是邪恶的

    尽管游标在某些情况下非常有用,但它们也被视为“邪恶”的,主要是因为它们打破了关系数据库的集合处理思维方式,可能导致性能下降,消耗更多资源,并降低并发性。 在面向集合的思维方式中,数据库查询通常一次性...

    oracle数据库游标实验报告

    oracle数据库游标实验报告!oracle数据库游标实验报告!oracle数据库游标实验报告!

    Oralce PLSQL存储过程之游标实践!

    ### Oracle PL/SQL 存储过程之游标实践详解 #### 一、引言 在Oracle数据库中,PL/SQL(Procedural Language for SQL)是一种强大的编程语言,它允许开发者编写复杂的数据库逻辑。其中,**游标**是PL/SQL中处理查询...

    我的第一次游标应用

    学习游标有一段时间了,也用过几次游标来解决问题,但是本次的应用让我更加深入的了解到游标的神奇!我写的这个程序是用在ERP系统中将库存分配到当天要出货的订单上,由于有订单不一定有库存,有库存的时候,当天不...

    波形图游标功能_获取游标_

    波形图游标功能在许多科学计算和数据分析应用中都是一种非常重要的工具,它允许用户在可视化图形上精确地定位和测量数据点。在LabVIEW(Laboratory Virtual Instrument Engineering Workbench)这样的图形化编程环境...

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

    ### Oracle中的游标详解 #### 一、引言 在Oracle数据库中,游标是一种非常重要的机制,它允许用户在程序中对查询结果进行逐行处理。游标分为两种主要类型:**隐式游标**和**显示游标**。此外,还可以利用游标进行...

    SQL Server 游标的简单使用

    SQL Server对游标的使用要遵循:声明游标–打开游标–读取数据–关闭游标–删除游标。下面让我们来看看几种常用游标是怎么使用的! 1、只读游标的使用(只能使用next提取数据) --声明一个只读游标 declare cur_stu ...

    oracle数据库的游标

    游标是Oracle数据库中一个重要的概念,它是一种在内存中用于存储SQL查询结果的临时工作区域。使用游标可以方便地访问查询结果集中的每一行,这对于处理大量数据是非常有用的。游标主要分为两种类型:显式游标和隐式...

    Mysql游标(循环操作)

    ### MySQL游标(循环操作) #### 一、游标简介 在MySQL中,游标是一种数据库对象,主要用于处理存储过程中的结果集。游标允许我们逐行地读取查询结果,这对于需要对每一行数据执行特定操作的情况非常有用。通过...

    LabVIEW 的游标图例

    游标图例用来显示图形中的游标,如图1所示。在图形上用游标可读取绘图区域上某个点的确切值,游标值会显示在游标图例中。  图1 图形缩放方式  图2 游标图例  选择游标图例右键快捷菜单的“创建游标”,在...

    Oracle存储过程游标详解

    "Oracle存储过程游标详解" Oracle 存储过程游标是指在 Oracle 数据库中使用游标来实现对结果集的处理和操作。游标可以分为静态游标和REF游标两种类型。静态游标是指结果集已经确实(静态定义)的游标,可以进一步...

    使用游标更新数据库

    使用游标更新数据库 使用游标更新数据库是指在游标定位下,修改或删除表中指定的数据行。使用游标对数据进行更新可以提高数据库的性能和效率。 1. 游标更新的基本概念 游标是数据库中的一种数据结构,它可以用来...

    获取多个游标的坐标8.2_labview获取游标_

    "获取多个游标的坐标8.2_labview获取游标_"这个主题主要关注如何在LabVIEW中有效地利用游标功能,特别是如何获取并操作多个游标在波形图上的位置信息。以下是对这一主题的详细阐述: 首先,我们需要理解LabVIEW中的...

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

    游标和异常处理 游标是 SQL 的一个内存工作区,由系统或用户以变量的形式定义。游标的作用就是用于临时存储从数据库中提取的数据块。在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将...

    SQL游标使用金典

    ### SQL游标使用详解 #### 一、游标概述 在深入探讨SQL游标的使用之前,我们先来了解一下什么是游标。游标是数据库管理系统的功能之一,它允许用户逐行处理查询结果集中的数据。通常情况下,当我们执行一个SELECT...

    游标卡尺的使用.ppt

    游标卡尺的使用 游标卡尺是一种常用的测量工具,广泛应用于机械制造、工程设计、建筑施工等领域。下面我们将详细介绍游标卡尺的构造、使用规则、分类、测量原理和读数方法。 一、游标卡尺的构造 游标卡尺由四个...

    oracle笔记游标的使用

    oracle笔记游标的使用,游标的详细代码案例,游标知识点笔记!

    游标算法_伪码.pdf

    ### 游标算法详解 #### 一、引言 在现代电子控制系统中,尤其是在汽车行业中,精确的角度测量对于实现各种安全关键系统至关重要。本篇旨在深入解析“游标算法”这一核心概念及其应用实例,通过分析给定伪代码示例,...

    oracle游标学习资料

    Oracle游标是数据库编程中非常重要的一个概念,它允许开发者逐行处理查询结果集,而不仅仅是一次性处理所有数据。在Oracle中,游标分为隐式游标和显式游标。 **一、游标简介** 游标的核心功能是提供一种方式来遍历...

    静态、动态sql及各种游标

    静态、动态SQL及各种游标 静态SQL和动态SQL是两种不同的SQL语句执行方式,分别应用于不同的场景中。静态SQL是指在PL/SQL中直接运行的SQL语句,没有什么特别之处。动态SQL则是指利用EXECUTE IMMEDIATE语句执行的SQL...

Global site tag (gtag.js) - Google Analytics