2012-03-30 35 views
2

我已经看到了一些看起来应该很好的生产代码,并且有80%的时间工作,但其他20%将停止返回并遍历无明显原因的数据库列表:sys.databases在光标跳过数据库

DECLARE c_UserDatabases CURSOR FOR 
    SELECT Name 
    FROM Sys.Databases SD (NOLOCK) 
    ORDER BY Name 

OPEN c_UserDatabases 
FETCH Next FROM c_UserDatabases INTO @v_DatabaseName 
WHILE @@FETCH_STATUS = 0 
    BEGIN 
     -- Query that takes a few minutes to run (using dynamic SQL and EXEC, etc) 
     FETCH Next FROM c_UserDatabases INTO @v_DatabaseName 
    END 

CLOSE c_UserDatabases 
DEALLOCATE c_UserDatabases 

这是在SQL Server 2008 SP3上。我注意到,如果您没有按名称排序,那么提及它的文章可能会在某些版本中出现,但没有任何信息表明这种失败情况。我认为我们可能会遇到罕见的情况,因为内部部分可能需要很长时间才能运行?

我想知道是否有其他人看过这个。我打算重写它来选择一个临时表和光标。

+1

你为什么在SYS.DATABASES上使用NOLOCK? – 2012-03-30 04:21:11

+0

我没有写代码。但是我听到一个问题,那就是用户/登录表上长时间运行的游标阻止了长时间运行的登录,并且之后可能会添加它作为安全措施?你为什么要问。 – 2012-03-30 04:30:26

回答

2

这是我的一个非常古老的问题,但得到的答复是,如果你迭代sys.databases中的游标类型应该是静态的。

否则,如果在迭代它时(即备份等)该表发生了某种情况,它可以跳过数据库。与sp_MSForeachDB相同。

谢天谢地,我们很久以前就搬过去了。是的,NOLOCK被取出。

1

虽然没有文档,但sp_MSForeachDB提供了一种针对所有数据库执行查询的好方法。这种方法会有帮助吗?

EXEC sp_MSForeachDB ' 
    SELECT * FROM [?].sys.tables 
'