如何检查光标是不是存在(打开状态)
Posted
技术标签:
【中文标题】如何检查光标是不是存在(打开状态)【英文标题】:How to check if cursor exists (open status)如何检查光标是否存在(打开状态) 【发布时间】:2011-09-15 12:09:55 【问题描述】:如何检查光标是否打开?因为很多时候我遇到错误'光标已经存在'。请告诉我如何检查光标是否已处于打开状态。
事实上,我已经关闭并在最后释放了它(CLOSE ppm_cursor; DEALLOCATE ppm_cursor;)但我仍然遇到同样的错误,可能是什么原因。
【问题讨论】:
"如何确保游标是否尚未处于打开状态。"也许你应该不这样做。通常,每次完成后都应关闭每个游标。您永远不会发现光标处于打开状态。 .... 或首先避免使用光标! .... wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them @s.Lott 我已经关闭并在文件末尾释放了它(CLOSE ppm_cursor; DEALLOCATE ppm_cursor;)但我仍然遇到同样的错误,可能是什么原因。 错误“光标已存在”意味着“我已经关闭并在文件末尾释放了它”是错误的。您需要尽快关闭。您需要编写一个显示错误的 TINY 示例程序。并发布带有错误消息的 TINY 示例程序。您可以编写的最小程序会给出错误。 【参考方案1】:您可以使用CURSOR_STATUS 函数来确定其状态。
IF CURSOR_STATUS('global','myCursor')>=-1
BEGIN
DEALLOCATE myCursor
END
【讨论】:
对于其他人尝试使用您自己打开的游标进行此操作,并且可能由于错误处理而被分配,您可能必须将global
部分更改为local
。臭名昭著的 SO 复制/粘贴的诅咒:-P【参考方案2】:
关闭游标,如果为空则释放它:
IF CURSOR_STATUS('global','myCursor') >= -1
BEGIN
IF CURSOR_STATUS('global','myCursor') > -1
BEGIN
CLOSE myCursor
END
DEALLOCATE myCursor
END
【讨论】:
很好,但可以考虑在内部 IF 周围添加开始/结束以避免混淆您的意图。我的第一个想法是你忘记了一个,然后记住 SQL 也不需要它用于单行......只是避免了一点混乱 两个游标状态的结果会不会不一样? 只是补充一点:如果您使用存储在脚本某处声明的局部变量中的游标(例如 DECLARE @cursorName CURSOR )在获取状态时使用适当的游标类型('variable'): CURSOR_STATUS('variable ','@cursorName')。 释放光标会自动关闭它。【参考方案3】:对 Gary W 提到的内容稍作改动,添加“SELECT”:
IF (SELECT CURSOR_STATUS('global','myCursor')) >= -1
BEGIN
DEALLOCATE myCursor
END
http://social.msdn.microsoft.com/Forums/en/sqlgetstarted/thread/eb268010-75fd-4c04-9fe8-0bc33ccf9357
【讨论】:
应该是IF (SELECT CURSOR_STATUS('global','myCursor')) >= -1
注意第一个开括号的位置。【参考方案4】:
我很少使用游标,但我在这里发现了另一个可以咬你的东西,游标名称的范围。
如果数据库 CURSOR_DEFAULT 是全局数据库,如果您在具有特定名称(例如“cur”)的存储过程中声明游标,并且在该游标打开时调用另一个存储的游标,则会收到“游标已存在”错误声明并打开同名游标的过程(例如“cur”)。嵌套存储过程在尝试打开“cur”时会出现错误。
运行这段 sql 来查看你的 CURSOR_DEFAULT:
select is_local_cursor_default from sys.databases where name = '[your database name]'
如果此值为“0”,那么如何命名嵌套光标很重要!
【讨论】:
【参考方案5】:当在 SSMS 中运行的存储过程在循环期间遇到错误时,我发生了这种情况,而游标正在用于迭代记录并且在它关闭之前。为了修复它,我在 CATCH 块中添加了额外的代码,以在光标仍处于打开状态时关闭它(使用 CURSOR_STATUS 作为此处建议的其他答案)。
【讨论】:
以上是关于如何检查光标是不是存在(打开状态)的主要内容,如果未能解决你的问题,请参考以下文章