游标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+='' 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+='' 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.

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

Sql Server中的游标最好只用于有主键或唯一键的表的更多相关文章

  1. SQL Server的外键必须引用的是主键或者唯一键(转载)

    问: In SQL Server , I got this error -> "There are no primary or candidate keys in the refere ...

  2. SQL Server 中的游标(cursor)

    http://www.cnblogs.com/Dlonghow/archive/2009/05/14/1456910.html 在数据库中,游标是一个十分重要的概念.游标提供了一种对从表中检索出的数据 ...

  3. SQL Server学习之路(二):主键和外键

    0.目录 1.定义 1.1 什么是主键和外键 1.2 主键和外键的作用 1.3 主键.外键和索引的区别 2.主键(primary key) 2.1 通过SSMS设置主键 2.2 通过SQL语句设置主键 ...

  4. SQL Server中的游标CURSOR

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

  5. SQL Server 数据库添加主键,唯一键,外键约束脚本

    -- 声明使用数据库use 数据库;go -- 添加主键(primary key)约束-- 基本语法-- 判断主键约束是否存在,如果存在则删除,不存在则添加if exists(select * fro ...

  6. sql server 中常用修改列 ,创建主外键操作

    表结构 CREATE TABLE [staff] ( [id] [varchar](50) NOT NUL L, [name] [varchar](50) NOT NULL, [password] [ ...

  7. 图解SQL Server:聚集索引、唯一索引、主键

    http://www.cnblogs.com/chenxizhang/archive/2010/01/14/1648042.html

  8. mysql中主键和唯一键的区别

    区别项 primary key(主键) unique(唯一键约束) 唯一性 可以 可以 是否可以为空 不可以 可以 允许个数 只能有1个 允许多个 是否允许多列组合 允许 允许

  9. SQL server中的T-SQL语句

    首先点击新建查询 如下图所示 创建数据库:create database 数据库名称 使用数据库:use 数据库名称 创建表:create table 表名 ( 代码 ) 输入完成执行时需选中 如果需 ...

随机推荐

  1. 26、redis中默认有多少个哈希槽?

    Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余 ...

  2. Git和Gitlab协同工作

    1.概述 在写这篇博客之前,为了更好的描述整个流程,本人亲自尝试了:从搭建到使用,下面就围绕这个流程来阐述整个过程,目录结构如下所示: Git的安装搭建 Git的常规操作 Gitlab的搭建 Gitl ...

  3. 对html中iframe的研究

    虽然平时不怎么用iframe,但经常在网上听一些前辈说iframe怎样怎样,今天索性对iframe来个大研究,那样就不必去记那些条条框框了,自己体验一遍比看什么都好. 创建两个文件一个index.ht ...

  4. es6学习笔记6--Generator 函数

    基本概念 Generator函数有多种理解角度.从语法上,首先可以把它理解成,Generator函数是一个状态机,封装了多个内部状态. 执行Generator函数会返回一个遍历器对象,也就是说,Gen ...

  5. IDEA破解教程(破解到2100年)的注意事项

    https://blog.csdn.net/yl1712725180/article/details/80309862 1.上边是教程 2.注意事项,在两个文件中加   -javaagent:加上你j ...

  6. 【转】GDI+中发生一般性错误的解决办法

    今天在开发.net引用程序中,需要System.Drawing.Image.Save 创建图片,debug的时候程序一切正常,可是发布到IIS后缺提示出现“GDI+中发生一般性错误”的异常. 于是开始 ...

  7. [编程] TCP协议概述

    TCP 协议概述 1.TCP提供一种面向连接的.可靠的字节流服务. 2.两个应用程序通过TCP连接交换8bit字节构成的字节流. 3.每个TCP首部都包含源端和目的端的端口号,用于寻找发端和收端应用进 ...

  8. SQL-Server多表关联查询并分页

    一.多表关联查询 1,left join RelaTimeLog表 和 ValidFlight表关联查询 order by t.FlightId desc 2,与group by连用 group by ...

  9. Java多线程--JDK并发包(2)

    Java多线程--JDK并发包(2) 线程池 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. JDK有一套Executor框架,大概包括Executor.Ex ...

  10. 编程输出杨辉三角的前10行---多维数组的应用---java实现

    import java.util.Scanner;public class yanghui{ public static void main(String[] args){  Scanner sc=n ...