【问题标题】:Should I be avoiding @@Fetch_Status?我应该避免@@Fetch_Status 吗?
【发布时间】:2012-10-14 15:14:09
【问题描述】:

经过阅读后,很明显多个过程可以修改全局变量@@Fetch_Status。我们有一个存储过程,它每小时调用一次其他存储过程(有点像表驱动的触发器,这样客户端可以控制但不必触摸一个触发器)。所以这个调用这些子过程的父过程使用游标。一些子过程也可以使用游标。

我知道每个Fetch Next 调用之后几乎都会紧接着一个@@Fetch_Status 调用,但是由于并行发生的事情,我不确定调用@@Fetch_Status 是否是线程安全的,尤其是考虑到备注强>部分here。所以我认为将我所有的 While @@Fetch_Status = 0) 调用替换为类似

WHILE ( (SELECT fetch_status
FROM sys.dm_exec_cursors(0)
where name = 'server_cursor')=0) BEGIN

这在我的计算机上运行良好,但当我将其移至客户端计算机时,我了解到我没有 sys.dm_exec_cursors(0) 表的选择权限。我收到错误The user does not have permission to perform this action.。

或者,如果我尝试select * from sys.syscursors,我会收到错误The SELECT permission was denied on the object 'syscursors', database 'mssqlsystemresource', schema 'sys'.

是否有另一种方法可以确保多个同时游标不会相互踩踏?还是我在这里工作太辛苦了?

【问题讨论】:

  • 当然,没有一个过程是这样写的,但是 procA 和 procB 是什么都使用游标,procA 调用下一行但在它可以检查获取状态 procB 之前,并行地获取它是最终的行因此将全局@@Fetch_Status 设置为-1。然后当 procA 去检查@@Fetch_Status它认为它的行都被提取但他们没有。还是 SQL 比这更聪明?
  • 来自单个连接的过程不会并行运行。唯一可以并行运行的是单个查询的并行执行计划。
  • 好的。相反,如果 ProcA 和 ProcB 都安排在上午 10 点执行会怎样。服务器是否并行运行这些?还是先做一个然后再做另一个?
  • 如果通过 SQL 代理进行调度,它们将在不同的 SPID(连接)下运行,因此不会看到彼此的 @@Fetch_Status。如果不是,请解释您所说的“预定”是什么意思

标签: sql-server-2005 cursor


【解决方案1】:

解决方案是在您的FETCH NEXT 语句之后检查@@FETCH_STATUS。特别是,确保没有可能改变状态的干预呼叫。如有必要,您可以将该值保存到已声明的局部变量中。您提到“几乎立即”检查状态。如果您不确定,最好检查您的代码。

否则,@@FETCH_STATUS 应该是可靠的。

【讨论】:

    猜你喜欢
    • 2014-10-24
    • 2022-12-16
    • 2010-09-23
    • 2020-12-15
    • 2010-10-15
    • 2020-10-05
    • 2018-06-16
    • 2011-12-31
    • 2021-06-03
    相关资源
    最近更新 更多