游标sql server_SQL Server游标属性

本文介绍了SQL Server游标的概念,以及如何创建和管理游标,包括LOCAL、GLOBAL、FORWARD_ONLY、SCROLL、STATIC、DYNAMIC、FAST_FORWARD等各种属性的详细解释和使用示例。通过示例展示了不同属性对游标行为的影响,帮助理解游标在数据库操作中的应用。
摘要由CSDN通过智能技术生成

游标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 Test
 
OPEN DefaultCursor
 
FETCH NEXT  FROM DefaultCursor  INTO @id, @name
 
WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT @id, @name
 
  FETCH NEXT  FROM DefaultCursor  INTO @id, @name
END
 
CLOSE DefaultCursor
 
DEALLOCATE 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,然后单击确定。

cursor default scope

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

LOCAL CURSOR

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 Test
 
 
OPEN DefaultCursor
 
FETCH NEXT  FROM DefaultCursor  INTO @id, @name
 
WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT @id, @name
 
  FETCH NEXT  FROM DefaultCursor  INTO @id, @name
END
 
CLOSE DefaultCursor
 
DEALLOCATE DefaultCursor

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

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

Local SQL Server cursor - 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

global SQL Server cursor

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'。 它将引发错误,如下图所示。

SQL Server cursor - FORWARD_ONLY

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获取选项时,请参考下图以获取结果集。

SQL Server scroll cursor

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 Test
 
 
OPEN 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 SQL Server cursor

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 Test
 
 
OPEN 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

SQL Server cursor - STATIC

动态 (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 Test
 
OPEN 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 
begin
 
FETCH NEXT  FROM DefaultCursor
end

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

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

SQL Server dynamic cursor

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在光标内进行更新和删除。 打开光标后发生的任何数据更改都不可见。

SQL Server read_only cursor

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 Test
 
OPEN DefaultCursor
 
FETCH 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.

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

SQL Server scroll_locks cursor

更新 (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 UPDATE
 
OPEN DefaultCursor
 
FETCH NEXT  FROM DefaultCursor  INTO @id, @name
 
WHILE @@FETCH_STATUS = 0
BEGIN
  UPDATE test set id =1 ,name ='Updatetest' where current of DefaultCursor
 
  FETCH NEXT  FROM DefaultCursor  INTO @id, @name
END
 
CLOSE DefaultCursor
 
DEALLOCATE 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 DefaultCursor
 
FETCH NEXT  FROM DefaultCursor  INTO @id, @name
 
WHILE @@FETCH_STATUS = 0
BEGIN
  UPDATE test set id =1 ,name ='Updatetest' where current of DefaultCursor
 
  FETCH NEXT  FROM DefaultCursor  INTO @id, @name
END
 
CLOSE DefaultCursor
 
DEALLOCATE 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.

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

for update attribute in a SQL Server cursor

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。 这将返回实例中所有数据库上打开的游标的信息。 这将返回信息,例如打开游标的会话,游标的名称和属性。 请参阅下图以了解内联函数返回的结果集。

SQL Server cursor - Properties

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值