代码之家  ›  专栏  ›  技术社区  ›  Joel Coehoorn

有关类似sp msforeachdb的查询的帮助

  •  1
  • Joel Coehoorn  · 技术社区  · 16 年前

    在我所在的位置,我们有一个软件包在主机系统上运行。大型机每晚向SQL Server进行一次转储,这样我们的每个客户机在服务器中都有自己的数据库。服务器实例中也有一些其他数据库,加上一些没有数据的旧客户端DBS。

    我们经常需要跨所有客户机运行报告或检查数据。我希望能够使用sp msforeachdb或类似的工具运行查询,但我不确定如何从列表中过滤不需要的dbs。你有什么想法吗?

    我们仍在使用SQL Server 2000,但应该在几个月后移到2005年。


    更新:
    我觉得我问这个问题做得不好,所以我要澄清我的目标,然后公布我最终使用的解决方案。

    我想在这里完成的是让在程序中使用查询的程序员使用一个客户机数据库编写查询变得容易,然后几乎立即运行(测试)代码,在所有50个左右的客户机DBS上设计并构建在一个客户机的DB上,几乎不做任何修改。

    考虑到这一点,下面是我的代码,因为它当前位于ManagementStudio中(部分模糊):

    use [master]
    declare @sql varchar(3900) 
    
    set @sql = 'complicated sql command added here'
    
    -----------------------------------
    declare @cmd1 varchar(100)
    declare @cmd2 varchar(4000)
    declare @cmd3 varchar(100)
    set @cmd1 = 'if ''?'' like ''commonprefix_%'' raiserror (''Starting ?'', 0, 1) with nowait'
    set @cmd3 = 'if ''?'' like ''commonprefix_%'' print ''Finished ?'''
    set @cmd2 = 
        replace('if ''?'' like ''commonprefix_%'' 
        begin 
            use [?]
            {0} 
        end', '{0}', @sql)
    
    exec sp_msforeachdb @command1 = @cmd1, @command2 = @cmd2, @command3 = @cmd3
    

    您所要做的就是将@sql变量设置为查询文本。很容易变成存储过程。它是动态SQL,但同样:它只用于开发(著名的遗言;)。缺点是,您仍然需要避开查询中使用的单引号,并且在大多数情况下,您最终会添加一个额外的引号。 ''?'' As ClientDB 列在选择列表中,但在其他情况下它工作得很好。

    除非今天我得到了另一个非常好的主意,否则我想将它转换为存储过程,并将一个版本作为表值函数放在一起,使用临时表将所有结果放在一个结果集中(仅用于选择查询)。

    4 回复  |  直到 16 年前
        1
  •  1
  •   jennykwan    16 年前

    只需将要在if-not中执行的语句包装在:

    EXEC    sp_msforeachdb  "
    IF      '?'     NOT IN ('DBs','to','exclude')   BEGIN
            EXEC    sp_whatever_you_want_to
    END
    "
    
        2
  •  0
  •   BradC    16 年前

    我们的每台数据库服务器都包含一个“DBA”数据库,其中包含了这样的满是元数据的表。

    “databases”表将保留服务器上所有数据库的列表,您可以放置标志列来指示数据库状态(live、archive、system等)。

    然后,脚本要做的第一件事就是转到DBA数据库,获取它应该运行的所有数据库的列表。

    我们甚至有一个夜间维护脚本,确保服务器上的所有物理数据库也被输入到我们的“dba.databases”表中,如果不输入,就会向我们发出警报。(因为向该表中添加行应该是手动过程)

        3
  •  0
  •   Paul Nearney    16 年前

    如何获取sp msforeachdb的定义,并根据您的目的对其进行调整?要获取定义,可以运行此命令(先按ctrl-t将结果窗格置于文本模式):

    sp_helptext sp_msforeachdb
    

    显然,您希望创建自己版本的存储过程,而不是覆盖原始存储过程;o)

        4
  •  0
  •   Sam    16 年前

    在2005年的SSIS包中,执行这种类型的操作非常简单。也许您可以在某个服务器上设置一个实例。

    我们已经设置了多个服务器,所以我们有一个表来指示将调查哪些服务器。然后,我们把所有数据库的列表拉回来。这用于备份脚本。

    您可以维护这个数据库列表,并为自己的目的添加一些字段。您可以有另一个包或步骤,这取决于您如何决定要报告哪些数据库以及是否可以通过编程方式完成。

    您可以在这里免费获得代码: http://www.sqlmag.com/Articles/ArticleID/97840/97840.html?Ad=1

    我们的系统基于此代码。

    推荐文章