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.

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

  • 相关阅读:
    一行代码轻松修改 Text Field 和 Text View 的光标颜色 — By 昉
    六种手势识别,你用了哪些?——董鑫
    Mac 屏幕录制Gif 制作 By-胡罗
    利用ICMP协议的PING命令获取客户端当前网络质量 by徐文棋
    iOS加载Gif图片的N种方式 By-H罗
    [手游项目3]-10-Go语言atomic原子操作
    [手游项目3]-9-Go语言sync.Map(在并发环境中使用的map)
    LRU原理和Redis实现
    Cleanup failed to process the following paths错误的解决
    [手游项目3]-8-排行榜redis实现
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/8421484.html
Copyright © 2011-2022 走看看