Mik*_*ike 31 t-sql sql-server cursor
将光标保持打开被称为不良做法.但是当你忘记关闭和/或解除分配时会发生什么?它如何影响SQL Server,连接/会话?使用游标的查询,存储过程和触发器的后果是否有任何差异?
Aar*_*and 31
这取决于您是在本地还是全局声明游标(以及您的环境中的默认值 - 默认是全局的,但您可以更改它).
如果光标是全局的,那么它可以在SQL Server中保持"活动"状态,直到在创建它的范围内触及最后一段代码.例如,如果您调用创建全局游标的存储过程,然后调用其他20个存储过程,则当其他20个存储过程正在运行时,游标将继续运行,直到调用者超出范围.我相信它会在会话级别保持活跃,而不是连接级别,但没有彻底测试.如果光标被声明为local,那么它应该只保留在当前对象的范围内(但同样,这是理论上的,我还没有进行大量的低级内存测试来确认).
但是,一般概念应该是:当你完成某些事情时,就这么说.
为了使我的游标尽可能高效,我总是使用以下声明:
DECLARE c CURSOR
LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR SELECT ...
Run Code Online (Sandbox Code Playgroud)
我也听说过,如果你只是CLOSE或者只是DEALLOCATE这样,我可能会在你完成时同时做两件事:
CLOSE c;
DEALLOCATE c;
Run Code Online (Sandbox Code Playgroud)
但是,你有多少游标清理这种语法是一个问题?如果你的系统中有数百个游标,那对我来说无疑是一个红旗.
编辑
作为附录,我只想澄清一下,游标本身并不坏.但是,它们经常被误用和滥用 - 在可以实现更高效,基于集合的解决方案的情况下实现,但负责编写查询的人只能在程序上进行思考.游标有意义的几个案例:
不关闭游标将使其保持锁定在它所在的行上.即使关闭后,引用仍保留在光标正在使用的数据结构中(因此可以重新打开)这些结构是特定于SQL服务器的(所以它不仅仅是内存空间或句柄等)并且取决于光标实际上是什么这样做,但它们通常是临时表或查询结果集.
不解除分配AFAIK只与性能有关.上述资源将保持分配状态,从而对服务器性能产生负面影响.
从(打开或关闭但未解除分配)游标分配的资源将保持分配,直到会话(或连接)关闭