美文网首页SQL Server
SQL-高级操作(锁、游标)

SQL-高级操作(锁、游标)

作者: 肉肉要次肉 | 来源:发表于2017-06-09 15:01 被阅读160次

    SQL Server 2008 的关键特性之一是支持多用户共享同一数据库,但是,当某些用户同时对同一个数据进行修改时,会产生一定的并发问题。使用事务便可以解决用户存取数据的这个问题,从而保证数据库的完整性和一致性。然而如果防止其他用户修改另一个还没完成的事务中的数据,就必须在事务中使用锁。

    SQL Server 2008 中提供了多种锁模式

    主要包括:排他锁、共享锁、更新锁、意向锁、键范围锁、架构锁 和 大容量更新锁。

    一、排他锁

    如果事务T1获得了数据项R上的排他锁,则T1对数据项既可读又可写。事务T1对数据项R加上排他锁,则其他事务对数据项R的任何封锁请求都不会成功,直至事务T1释放数据项R上的排他锁。

    二、共享锁

    如果事务T1获得了数据项R上的共享锁,则T1对数据项R可以读但不可以写。事务T1对数据项R加上共享锁,则其他事务对数据项R的排他锁请求不会成功,而对数据项R的共享锁请求可以成功。

    三、更新锁

    更新锁可以防止死锁情况出现。当一个事务查询数据以便进行修改时,可以对数据项施加更新锁,如果事务修改资源,则更新锁会转换成排他锁。否则会转换成共享锁。一次只有一个事务可以获得资源上的更新锁,它允许其他事务对资源的共享式访问,但阻止排他锁式的访问。

    四、意向锁

    意向锁用来保护共享锁或排他锁放置在锁层次结构的底层资源上。之所以命名为意向锁,是因为在较低级别锁前可获取它们,因此会通知意向锁将锁放置在较低级别上。

    五、键范围锁

    键范围锁可防止幻读。通过保护行之间键的范围,它还防止对事务访问的记录集进行幻象插入或删除

    六、架构锁

    执行表的DDL操作(例如添加列)时使用架构修改锁。在架构修改锁起作用的期间,会防止对表的并发访问。这意味着在释放架构修改锁之前,该锁之外的所有操作都将被阻止

    七、大容量更新锁

    大容量更新锁允许多个进程将数据并行地大容量复制到同一表,同时防止其他不进行大容量复制的进程访问该表。


    幻读是指当事务不是独立执行时发生的一种现象。比如,事务T1对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,事务T2也修改了这个表中的数据,但是只向表中插入一行数据,那么,以后就会发生操作事务T2的用户更新数据后,却发现表中还有没有修改的数据行,就好像虚幻似的。


    使用sys.dm_tran_locks可以快速了解SQL Server 2008 内的加锁情况。在默认情况下,任何一个拥有VIEW SERVER STATE权限的用户均可以查询sys.dm_tran_locks视图。

    语句如下:

    SELECT * FROM  sys.dm_tran_locks




    游标


    游标(Cursor)是类似于C语言指针一样的结构,在SQL Server 2008 中它是一种数据访问机制,允许用户访问单独的数据行,而不是对整个行集进行操作。用户可以通过单独处理每一行逐条收集信息并对数据逐行进行操作,从而降低系统开销和潜在的阻隔情况。用户也可以使用这些数据生成SQL代码并立即执行或输出。

    在SQL Server 2008 中游标主要包括游标结果集游标位置两部分。

    游标结果集:是由定义游标的SELECT 语句返回行的集合

    游标位置:是指向这个结果集中的某一行的指针。

    游标特点


    1、游标返回一个完整的结果集,但允许程序设计语言只调用集合中的一行

    2、允许定位在结果集的特定集

    3、从结果集的当前位置检索一行或多行

    4、支持对结果集中当前位置的行进行数据修改

    5、可以为其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持

    6、提供脚本、存储过程和触发器中使用的访问结果集中数据的T-SQL语句

    注意:在使用游标之前首先要声明游标,定义T-SQL服务器游标的属性,例如游标的滚动行为和用于生成游标所操作的结果集的查询。

    游标语法如下:

    DECLARE 游标名 CURSOR

    例如:为userInfo表创建一个普通的游标,定义名称为user_cursor

    图1 创建普通游标

    在声明游标以后,就可以对游标进行操作。主要包括:打开游标、检索游标特定行、关闭游标和释放游标

    1、打开游标

    使用游标之前必须首先打开游标,语法如下:

    OPEN 游标名

    图2 打开游标

    一旦打开了游标,就可以用@@CURSOR_ROWS全局变量检索游标中的行数。但要注意的是,在某些条件下@@CURSOR_ROWS并不反映游标中的实际行数。

    2、检索游标

    在打开游标之后,就可以打开游标提取数据。FETCH语句就是用来从游标中将数据检索出来的,以便用户能够使用这个数据。FETCH语句就是用来移动这个记录指针的。

    FETCH   【NEXT / PRIOR / FIRST / LAST / ...】 

    FROM  游标名

    下面所示就是使用FETCH语句来打开user_cursor游标之后,检索游标中的可用数据:

    图3 检索游标

    上述语句中的@@FETCH_STATUS全局变量保存的是FETCH操作的结束信息。如果其值为零,则表示有记录检索成功。如果值不为零,则FETCH语句由于某种原因而操作失败。

    3、关闭游标

    在打开游标以后,SQL Server 2008服务器会专门为游标开辟一定的内存空间以存放游标操作的数据结果集。同时游标的使用也会根据具体情况对某些数据进行封锁。所以在不使用游标的时候,一定要关闭游标,以通知服务器释放游标所占用的资源。

    语法如下:

    CLOSE  游标名

    图4 关闭游标

    4、释放游标

    游标结构本身也会占用一定的计算机资源,所以在使用完游标后,为了回收被游标占用的资源,应该将游标释放。当释放最后的游标引用时,组成该游标的数据结构由SQL Server 2008 释放。

    语法如下:

    DEALLOCATE  游标名

    图5 释放游标

    相关文章

      网友评论

        本文标题:SQL-高级操作(锁、游标)

        本文链接:https://www.haomeiwen.com/subject/znpxqxtx.html