【发布时间】:2012-03-07 16:45:59
【问题描述】:
让光标保持打开状态是一种不好的做法。
- 但是当您忘记关闭和/或释放它时,会发生什么?
- 它如何影响 SQL Server、连接/会话?
- 使用游标的查询、存储过程和触发器的结果有什么不同吗?
【问题讨论】:
标签: sql-server tsql database-cursor
让光标保持打开状态是一种不好的做法。
【问题讨论】:
标签: sql-server tsql database-cursor
这取决于您是在本地还是全局声明光标(以及您的环境中的默认值 - 默认值是全局的,但您可以更改它)。
如果光标是全局的,那么它可以在 SQL Server 中保持“活动”状态,直到最后一段代码在创建它的范围内被触及。例如,如果您调用一个创建全局游标的存储过程,然后调用 20 个其他存储过程,则游标将在其他 20 个存储过程运行时继续存在,直到调用者超出范围。我相信它会在会话级别而不是连接级别保持活跃,但尚未对此进行彻底测试。如果游标被声明为本地,那么它应该只停留在当前对象的范围内(但同样,这是理论上的,我还没有进行广泛的低级内存测试来确认)。
不过,一般概念应该是:当你完成某事时,说出来。
为了使我的游标尽可能高效,我总是使用以下声明:
DECLARE c CURSOR
LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR SELECT ...
我还听说如果您只使用 CLOSE 或仅使用 DEALLOCATE 可能会出现内存问题,所以我总是在完成后同时做这两个:
CLOSE c;
DEALLOCATE c;
但是,您有多少游标来清理这种语法是个问题?如果您的系统中有数百个游标,那对我来说肯定是一个危险信号。
编辑
作为附录,我只是想澄清一下游标本身并不坏。但是,它们经常被误用和滥用 - 在可以实施更有效的基于集合的解决方案的情况下实施,但负责编写查询的人只能在程序上思考。游标有意义的几种情况:
【讨论】:
“游标变量不必显式释放。当变量超出范围时,它会被隐式释放。”
【讨论】:
不关闭游标将保持它所在行上的锁处于活动状态。 即使关闭了对游标正在使用的数据结构的引用(因此可以重新打开) 这些结构是特定于 SQL 服务器的(因此它不仅仅是内存空间或句柄等)并且取决于游标实际在做什么,但它们通常是临时表或查询结果集。
不解除分配 AFAIK 仅与性能有关。上述资源将保持分配状态,因此会对服务器性能产生负面影响。
从(打开或关闭,但未释放)游标分配的资源将保持分配状态,直到会话(或连接)关闭
【讨论】: