【发布时间】: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。如果不是,请解释您所说的“预定”是什么意思