zoukankan      html  css  js  c++  java
  • Sql Server中的游标最好只用于有主键或唯一键的表

    游标cursor,我想大多数人都在sql server里面用过。当一个表数据量不太大的时候,游标还是可以用的,毕竟游标是循环一个表中每一行数据的最简便办法。但是如果你用一个游标去循环一个没有主键或唯一键的表会发生什么呢?

    我们来看看这个例子,我们声明了一个临时表#Foo并插入了一行数据,这个表没有主键,然后我们使用了一个名叫ID的游标去更新这个表[Name]列的数据,执行下面的语句看看会发生什么?

    CREATE TABLE #Foo(
        [ID] [smallint] IDENTITY(1,1),
        [Code] [char](3) NULL,
        [Name] [varchar](50) NULL,
        [ProvinceID] [tinyint] NULL
    )
    go
    Insert #Foo(Code, Name, ProvinceID)
    Select 'A', 'New York', 3;
    
    Declare ID Cursor  For  Select top 5  ID From  #Foo Order by ID 
    Open ID;
    Fetch From ID ;
    Update #Foo Set Name+='1' Where Current OF ID
    Close ID ;
    Deallocate ID 
    
    Select * From #Foo
    go
    
    Drop Table #Foo

    执行结果如下:

    你会发现sql server报错了,提示你声明的游标ID是一个READ_ONLY的只读游标。READ_ONLY游标意味着声明的游标只能读取数据,游标不能做任何更新操作,而我们上面的语句使用了游标ID来更新表#Foo的数据,所以报错了。

    现在我们把上面的语句改成下面的,主要就是在声明表#Foo的时候将列[ID]声明为了主键,再执行下面的语句:

    CREATE TABLE #Foo(
        [ID] [smallint] IDENTITY(1,1),
        [Code] [char](3) NULL,
        [Name] [varchar](50) NULL,
        [ProvinceID] [tinyint] NULL
     CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )
    )
    go
    Insert #Foo(Code, Name, ProvinceID)
    Select 'A', 'New York', 3;
    
    Declare ID Cursor  For  Select top 5  ID From  #Foo Order by ID 
    Open ID;
    Fetch From ID ;
    Update #Foo Set Name+='1' Where Current OF ID
    Close ID ;
    Deallocate ID 
    
    Select * From #Foo
    go
    
    Drop Table #Foo

    执行结果如下:

    这一次游标ID没有报错了,语句顺利执行。

    为什么将游标用于不带主键或唯一键的表后,游标会变为READ_ONLY的? 

    If your table does not have a unique index (or a primary key constraint or unique key constraint, both of which create a unique index behind the scenes), then you dynamic cursor is converted to a static cursor.  And all static cursors must be read only. 

    If one of the tables referenced by the CURSOR has no unique index, the CURSOR will be converted to STATIC. And STATIC cursors are READ-ONLY. See Using Implicit Cursor Conversions for more information.

    所以使用游标的时候最好都给表加上主键或唯一键,这样使用游标更新数据的时候就不会报错了。

  • 相关阅读:
    使用js对WGS-84 ,GCJ-02与BD-09的坐标进行转换
    百度地图初次使用的一些方法的介绍和静态行驶轨迹,点击当前行驶路径,进行高亮显示
    js数组代码库
    docker学习笔记4-Compose
    Linux and the Unix Philosophy(5)
    Linux and the UnixPhilosophy(4)
    docker原理讲解1-linux namespace
    Docker学习笔记3-生成镜像
    Docker学习笔记2-容器基本使用
    CentOS7下更新jenkins
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/8421484.html
Copyright © 2011-2022 走看看