游标sql server

A SQL Server cursor is a database object that is used to process the data in a set row by row. In this article, we will review how to create a cursor and different attributes used while declaring a cursor.

SQL Server游标是一个数据库对象,用于逐行处理设置的数据。 在本文中,我们将回顾如何创建游标以及在声明游标时使用的不同属性。

创建光标 (Creating cursor)

Below are the steps involved in creating a cursor.

以下是创建游标所涉及的步骤。

  • Declare – Declares the cursor with a name and the select statement which populates the result set 声明 –使用名称声明游标,并使用选择语句填充结果集
  • Open – Opens a cursor and populates the cursor by executing the select statement which is specified while declaring a cursor 打开 –打开游标并通过执行在声明游标时指定的select语句来填充游标
  • Fetch – To retrieve a specific row from the cursor based on the fetch arguments like NEXT, FIRST, LAST, etc 提取 –根据诸如NEXT,FIRST,LAST等的提取参数从游标中检索特定行
  • Close – Closes the current result set of SQL Server cursor and can be reopened 关闭 –关闭SQL Server游标的当前结果集,可以重新打开
  • Deallocate – Removes cursor reference and releases all the resources associated with a cursor DEALLOCATE -删除光标参考,并释放所有与游标相关联的资源

Let us create a sample table, insert a few rows and perform cursor operations on the table with different attributes.

让我们创建一个示例表,插入几行并对具有不同属性的表执行光标操作。

CREATE TABLE Test (  id INT, Name VARCHAR(50)  )INSERT INTO Test values (1,'John')
INSERT INTO Test values (2,'Mike')

The syntax for creating a cursor with default attributes.

用于创建具有默认属性的游标的语法。

DECLARE @id INT, @name VARCHAR(50)DECLARE DefaultCursor CURSOR
FOR
SELECT id, name FROM TestOPEN DefaultCursorFETCH NEXT  FROM DefaultCursor  INTO @id, @nameWHILE @@FETCH_STATUS = 0
BEGINSELECT @id, @nameFETCH NEXT  FROM DefaultCursor  INTO @id, @name
ENDCLOSE DefaultCursorDEALLOCATE DefaultCursor

By default, the scope of the cursor is defined based on the Default cursor setting at the database level. To check or change the current setting, navigate to the database in SQL Server management studio, right click on the database and click on Properties. Click on Options. You can see the current setting is GLOBAL in this case. If you want to change the default scope of SQL Server cursor, then click on the drop down and change it to LOCAL and click on OK

默认情况下,基于数据库级别的“ 默认”游标设置来定义游标的范围。 要检查或更改当前设置,请导航到SQL Server Management Studio中的数据库,右键单击数据库,然后单击“ 属性” 。 单击选项。 在这种情况下,您可以看到当前设置为GLOBAL 。 如果要更改SQL Server游标的默认范围,请单击下拉列表并将其更改为LOCAL,然后单击确定。

You can also change this setting using T-SQL. Execute the below statement to change the default setting to LOCAL.

您也可以使用T-SQL更改此设置。 执行以下语句,将默认设置更改为LOCAL。

USE [master]
GO
ALTER DATABASE [SampleDatabase] SET CURSOR_DEFAULT  LOCAL WITH NO_WAIT
GO

Execute the below statement to change the default setting to GLOBAL. Replace database name with your database name.

执行以下语句,将默认设置更改为GLOBAL。 用您的数据库名称替换数据库名称。

USE [master]
GO
ALTER DATABASE [SampleDatabase] SET CURSOR_DEFAULT  GLOBAL WITH NO_WAIT
GO

本地 (LOCAL)

If the cursor is created with LOCAL attribute then the scope of the cursor is limited to that batch, stored procedure or trigger in which the cursor was created.

如果使用LOCAL属性创建了游标,则游标的范围将限于创建游标的批处理,存储过程或触发器。

Let us try declaring a local cursor in one batch and open it in another batch.

让我们尝试在一批中声明一个本地游标,然后在另一批中打开它。

DECLARE DefaultCursor CURSOR LOCAL
FOR
SELECT id, name FROM Test

And when you try to open the SQL Server cursor in another batch it throws errors as the scope of the cursor is limited to a batch where it was created. Please refer to the below image for the error.

而且,当您尝试在另一个批处理中打开SQL Server游标时,由于游标的范围仅限于在其中创建了该批处理的游标,它会引发错误。 请参考下图以了解错误。

OPEN DefaultCursor

All the statements referencing the cursor name should go in one batch if the cursor is declared with local attribute.

如果使用局部属性声明了游标,则所有引用游标名称的语句都应成批处理。

DECLARE @id INT, @name VARCHAR(50)DECLARE DefaultCursor CURSOR LOCAL
FOR
SELECT id, name FROM TestOPEN DefaultCursorFETCH NEXT  FROM DefaultCursor  INTO @id, @nameWHILE @@FETCH_STATUS = 0
BEGINSELECT @id, @nameFETCH NEXT  FROM DefaultCursor  INTO @id, @name
ENDCLOSE DefaultCursorDEALLOCATE DefaultCursor

Please refer to the below image when the cursor is declared as local and all the referencing statements are executed in one batch.

当游标被声明为本地且所有引用语句都在一批中执行时,请参考下图。

全球 (GLOBAL)

If the cursor is created with GLOBAL attribute, the scope is cursor is not limited to the batch where it was created, and the cursor name can be referenced by any batch in the same connection.

如果使用GLOBAL属性创建游标,则范围的游标不限于创建游标的批次,并且同一连接中的任何批次均可引用游标名称。

Let us declare SQL Server cursor with a global attribute in one batch and try to use the cursor reference in another batch.

让我们在一批中声明带有全局属性SQL Server游标,然后尝试在另一批中使用游标引用。

DECLARE DefaultCursor CURSOR GLOBAL
FOR
SELECT id, name FROM Test

Now we will open cursor and fetch the current record in another batch.

现在,我们将打开游标,并在另一批中获取当前记录。

OPEN DefaultCursor
FETCH NEXT FROM DefaultCursor

We must issue a DEALLOCATE command on the cursor to remove the cursor references or the cursor references will be removed only on closing the connection.

我们必须在游标上发出DEALLOCATE命令以删除游标引用,否则游标引用将仅在关闭连接时被删除。

FORWARD_ONLY (FORWARD_ONLY)

When a cursor is specified with FORWARD_ONLY, it can be scrolled from first to the last row using fetch next. All other fetch options are not supported. All the data changes made by other users before fetching the row are visible.

当使用FORWARD_ONLY指定光标时,可以使用fetch next将光标从第一行滚动到最后一行。 不支持所有其他提取选项。 其他用户在获取该行之前所做的所有数据更改都是可见的。

Let us create a FORWARD_ONLY cursor and try to use other fetch options like ‘LAST’ and ‘PRIOR’. It throws an error as shown in the below image.

让我们创建一个FORWARD_ONLY游标,然后尝试使用其他提取选项,例如'LAST'和'PRIOR'。 它将引发错误,如下图所示。

Only FETCH NEXT option is supported when the cursor is created with FORWARD_ONLY.

使用FORWARD_ONLY创建光标时,仅支持FETCH NEXT选项。

滚动 (SCROLL)

When a cursor is created with SCROLL attribute, all the fetch options are available. Below are different fetch options available.

使用SCROLL属性创建游标时,所有获取选项均可用。 以下是可用的不同提取选项。

  • FIRST 第一
  • LAST 持续
  • PRIOR 先验
  • NEXT 下一个
  • RELATIVE 相对的
  • ABSOLUTE 绝对

Please refer to the below image for result set when a cursor is created with scroll and used LAST and PRIOR fetch options.

使用滚动创建光标并使用LAST和PRIOR获取选项时,请参考下图以获取结果集。

All the data changes made after opening the cursor are not visible. Create a cursor with a scroll and open it first.

打开光标后所做的所有数据更改都不可见。 创建带有滚动条的光标,然后首先将其打开。

DECLARE DefaultCursor  CURSOR  SCROLL
FOR
SELECT id, name FROM TestOPEN DefaultCursor

Now open another session in SQL Server management studio and update the record where id=1

现在在SQL Server Management Studio中打开另一个会话并更新id = 1的记录

Update TEST set Name ='Lee' WHERE ID =1

Now go back to a session where the SQL Server cursor was created on executing below fetch statement. It still shows the old value.

现在返回到在执行以下fetch语句时创建SQL Server游标的会话。 它仍然显示旧值。

FETCH NEXT FROM DefaultCursor

SCROLL and FAST_FORWARD attributes cannot be specified together in a cursor.

不能在游标中一起指定SCROLL和FAST_FORWARD属性。

静态的 (STATIC)

Static cursor when opened creates a copy of the data returned by the select statement specified in declare statement and any further data changes are not visible. We cannot update or delete data in using the CURRENT OF as it is read-only.

静态游标在打开时会创建声明语句中指定的select语句返回的数据的副本,并且看不到任何其他数据更改。 我们无法使用CURRENT OF来更新或删除数据,因为它是只读的。

Create a cursor with STATIC and open it first.

使用STATIC创建一个游标,然后首先将其打开。

DECLARE DefaultCursor  CURSOR  STATIC
FOR
SELECT id, name FROM TestOPEN DefaultCursor

Now open another session in SQL Server management studio and update the record where id=1

现在在SQL Server Management Studio中打开另一个会话并更新id = 1的记录

Update TEST set Name ='Peter' WHERE ID =2

Now go back to a session where the cursor was created on executing below fetch statement two times. It still shows the old value.

现在返回到在两次在fetch语句下面执行时创建游标的会话。 它仍然显示旧值。

FETCH NEXT FROM DefaultCursor

动态 (DYNAMIC)

When a cursor is created with dynamic attribute all the changes made to rows inside cursor or outside cursor are visible when you fetch the new record. By default, if STATIC or FAST_FORWARD is not specified the cursor is created as dynamic.

使用动态属性创建游标时,在获取新记录时,对游标内或游标外的行所做的所有更改都是可见的。 默认情况下,如果未指定STATIC或FAST_FORWARD,则将游标创建为动态游标。

To illustrate this, declare and opening the cursor.

为了说明这一点,请声明并打开游标。

DECLARE DefaultCursor CURSOR DYNAMIC
FOR
SELECT id, name FROM TestOPEN DefaultCursor

In another session insert few more records or update them.

在另一个会话中,再插入几条记录或更新它们。

INSERT INTO Test values (3,'Palmer')Update Test set Name ='Kevin' where id =1

Now issue a fetch statement in the same session where you created a cursor.

现在,在创建游标的同一会话中发出fetch语句。

FETCH NEXT FROM DefaultCursor
while @@FETCH_STATUS =0
beginFETCH NEXT  FROM DefaultCursor
end

We can see the data changes done outside of the cursor are reflected while fetching rows.

我们可以看到,在获取行时,反映了在游标之外完成的数据更改。

FAST_FORWARD (FAST_FORWARD)

This enables READ_ONLY and FORWARD_ONLY on the cursor. This is the fastest SQL Server cursor and any changes to data are not visible once the cursor is opened. FAST_FORWARD cannot be specified along with SCROLL or FOR_UPDATE.

这将启用游标上的READ_ONLY和FORWARD_ONLY。 这是最快SQL Server游标,一旦打开游标,对数据的任何更改都不可见。 不能与SCROLL或FOR_UPDATE一起指定FAST_FORWARD。

The syntax for creating a cursor with FAST_FORWARD

使用FAST_FORWARD创建游标的语法

DECLARE DefaultCursor CURSOR FAST_FORWARD
FOR
SELECT id, name FROM Test
order by ID

只读 (READ_ONLY)

This attribute on the cursor will not allow updates and deletes within the cursor using the CURRENT OF. Any data changes that occurred after opening cursor is not visible.

光标上的此属性将不允许使用CURRENT OF在光标内进行更新和删除。 打开光标后发生的任何数据更改都不可见。

SCROLL_LOCKS (SCROLL_LOCKS)

When the cursor is created with SCROLL_LOCKS attribute the rows which are fetched into cursor are locked.

使用SCROLL_LOCKS属性创建游标时,锁入到游标中的行。

Execute the below statements to create a cursor with SCROLL_LOCKS.

执行以下语句以使用SCROLL_LOCKS创建游标。

DECLARE DefaultCursor CURSOR SCROLL_LOCKS
FOR
SELECT id, name FROM TestOPEN DefaultCursorFETCH NEXT FROM DefaultCursor

Now open another session in SQL Server management studio and try to update the data in the table. It will be blocked by the above SQL Server cursor.

现在,在SQL Server Management Studio中打开另一个会话,然后尝试更新表中的数据。 它将被上述SQL Server游标阻止。

UPDATE TEST SET NAME = 'LockTest'

乐观的 (OPTIMISTIC)

This attribute will not update or delete data inside the cursor by using the CURRENT OF when the data is modified by another user in a different session after fetch. It throws an error as shown in the below image.

当另一个用户在获取数据后在另一个会话中修改该数据时,该属性将不会使用CURRENT OF来更新或删除游标内部的数据。 它将引发错误,如下图所示。

It compares timestamp or checksum to see if the row was modified after fetch.

它比较时间戳或校验和,以查看提取后是否修改了该行。

更新 (FOR UPDATE)

This attribute specifies the updatable columns in the cursor. Only columns which are specified are updatable. If no column list was provided all columns of the table can be updated.

此属性指定游标中的可更新列。 仅指定的列是可更新的。 如果未提供列列表,则可以更新表的所有列。

Sample cursor with no columns specified for an update. In this case, all columns in the table test can be updated inside the SQL Server cursor using the CURRENT OF.

没有为更新指定列的示例游标。 在这种情况下,可以使用CURRENT OF在SQL Server游标中更新表测试中的所有列。

DECLARE @id INT, @name VARCHAR(50)DECLARE DefaultCursor CURSOR
FOR
SELECT id, name FROM Test
FOR UPDATEOPEN DefaultCursorFETCH NEXT  FROM DefaultCursor  INTO @id, @nameWHILE @@FETCH_STATUS = 0
BEGINUPDATE test set id =1 ,name ='Updatetest' where current of DefaultCursorFETCH NEXT  FROM DefaultCursor  INTO @id, @name
ENDCLOSE DefaultCursorDEALLOCATE DefaultCursor

Sample cursor with only one column specified in the update list. In this case, we cannot update the column “id”.

在更新列表中仅指定一列的示例光标。 在这种情况下,我们无法更新“ id”列。

DECLARE @id INT, @name VARCHAR(50)DECLARE DefaultCursor CURSOR
FOR
SELECT id, name FROM Test
FOR UPDATE of [name]OPEN DefaultCursorFETCH NEXT  FROM DefaultCursor  INTO @id, @nameWHILE @@FETCH_STATUS = 0
BEGINUPDATE test set id =1 ,name ='Updatetest' where current of DefaultCursorFETCH NEXT  FROM DefaultCursor  INTO @id, @name
ENDCLOSE DefaultCursorDEALLOCATE DefaultCursor

If we try to update the column which is not in the update of the list, then it throws an error as shown in below image.

如果我们尝试更新不在列表更新中的列,则它将引发错误,如下图所示。

To view properties of the cursor, use inline function sys.dm_exec_cursors. This returns the information of open cursors on all databases in the instance. This returns the information like on which session the cursor was opened, name of the cursor and properties. Please refer to below image for result set returned by the inline function.

要查看游标的属性,请使用内联函数sys.dm_exec_cursors。 这将返回实例中所有数据库上打开的游标的信息。 这将返回信息,例如打开游标的会话,游标的名称和属性。 请参阅下图以了解内联函数返回的结果集。

I hope you have benefitted from this SQL Server cursor article. Feel free to provide feedback in the comments below.

希望您从这篇SQL Server游标文章中受益。 请随时在下面的评论中提供反馈。

翻译自: https://www.sqlshack.com/sql-server-cursor-attributes/

游标sql server

游标sql server_SQL Server游标属性相关推荐

  1. 游标sql server_SQL Server游标教程

    游标sql server 介绍 (Introduction) 大多数使用Microsoft SQL Server的人至少会听说过游标,而且即使人们基本了解SQL Server游标的作用,他们也不总是确 ...

  2. 游标sql server_SQL Server游标性能问题

    游标sql server 介绍 (Introduction) 在上一篇文章中,我们讨论了如何设置基本游标. 我们解释了游标是基于行的操作,它采用给定的SELECT语句并将数据处理分解为循环执行. 没有 ...

  3. 游标sql server_了解游标并将其替换为SQL Server中的JOIN

    游标sql server Relational database management systems including SQL Server are very good at processing ...

  4. 索引sql server_SQL Server索引结构和概念

    索引sql server In my previous article, SQL Server Table Structure Overview, we described, in detail, t ...

  5. 索引sql server_SQL Server索引设计基础和准则

    索引sql server In the previous article of this series, SQL Server Index Structure and Concepts, we des ...

  6. java 调试sql server_sql server 如何调试存储过程

    PHP面试干货 1.进程和线程 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性.进程和线程的区别在于: 简而言之,一个程序至少有一个进程,一个进程至少有一 ...

  7. 索引sql server_SQL Server索引操作

    索引sql server In the previous articles of this series, we described the structure of the SQL Server t ...

  8. 索引sql server_SQL Server索引–系列介绍

    索引sql server 描述 (Description) In this series, we will dive deeply in the SQL Server Indexing field, ...

  9. 索引sql server_SQL Server报告– SQL Server索引利用率

    索引sql server Understanding indexing needs allows us to ensure that important processes run efficient ...

最新文章

  1. DELL本本 执行SQL语句要FN+F5 如何更改成F5
  2. 分支-19. 阶梯电价
  3. intel 汇编中断解释
  4. 强化学习中的调参经验与编程技巧(on policy篇)
  5. 新同事,git又报错Please move or remove them before you merge
  6. 采用多播传送FIX行情数据的推荐方案
  7. koa-generator 快速生成 koa2 服务的脚手架工具
  8. 2018 NLPCC Chinese Grammatical Error Correction 论文小结
  9. 设计模式-Decorator装饰模式
  10. LINUX编译Android FFmpeg:fatal error: errno.h: No such file or directory
  11. ILSpy-Reflexil修改UnityEditor.Timeline.dll
  12. linux运行perl脚本,linux运行perl脚本_将Perl脚本从Solaris移植到Linux
  13. FusionChartsFree调用json数据的简单例子
  14. 【T3】打印凭证没有任何反应
  15. 矩阵平方差公式成立条件的探讨
  16. 利盟 x466 双面打印问题之正反面颠倒
  17. “恶意版”俄罗斯方块游戏火了
  18. 卧槽,javaCV不到十行代码实现图片OCR文字识别
  19. 外贸客户催货催的很急的原因
  20. 查询oracle原始表d,oracle 多表查询

热门文章

  1. 特别困的学生(Extraordinarily Tired Students, ACM/ICPC Xi'an 2006, UVa12108)
  2. Chrome 远程调试协议分析与实战
  3. Go语言学习笔记——Go语言数据类型
  4. 前端知识整理 CSS盒模型
  5. 【转】sql server 订阅发布、快照发布(一)
  6. InvocationTargetException异常
  7. 分享这几天做seo优化的心得
  8. 【Vue】样式穿透 ::v-deep的具体使用
  9. 【Vue】—计算属性缓存VS方法以及侦听器的区别
  10. VSCode 设置代码自动保存!!!