【问题标题】:Help with sp_msforeachdb -like queries帮助 sp_msforeachdb 类似查询
【发布时间】:2010-10-05 06:47:52
【问题描述】:

我在哪里,我们有一个在大型机系统上运行的软件包。大型机每晚都会转储到 sql server 中,这样我们的每个客户端在服务器中都有自己的数据库。服务器实例中还有一些其他数据库,以及一些没有数据的旧客户端数据库。

我们经常需要跨所有客户运行报告或检查数据。我希望能够使用 sp_msforeachdb 或类似的东西运行查询,但我不确定如何从列表中过滤不需要的数据库。关于这如何工作的任何想法?

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


更新:
我认为我在问这个问题时做得很差,所以我要澄清我的目标,然后发布我最终使用的解决方案。

我想在这里完成的是让从事查询以在其程序中使用的程序员能够轻松地使用一个客户端数据库编写查询,然后几乎立即运行(测试)在一个客户端的数据库上设计和构建的代码在所有 50 个左右的客户端数据库上,几乎没有修改。

考虑到这一点,这是我目前位于 Management Studio 中的代码(部分混淆):

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 列,但除此之外它工作得很好。

除非我今天有另一个非常好的主意,否则我想把它变成一个存储过程,并将一个版本组合成一个表值函数,使用一个临时表将所有结果放在一个结果集中(仅适用于选择查询) .

【问题讨论】:

    标签: sql-server tsql sp-msforeachdb


    【解决方案1】:

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

    我们设置了多台服务器,因此我们有一个表格来指示将调查哪些服务器。然后,除其他事项外,我们拉回所有数据库的列表。这用于备份脚本。

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

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

    我们的系统基于此代码。

    【讨论】:

      【解决方案2】:

      只需将要执行的语句包装在 IF NOT IN 中:

      EXEC    sp_msforeachdb  "
      IF      '?'     NOT IN ('DBs','to','exclude')   BEGIN
              EXEC    sp_whatever_you_want_to
      END
      "
      

      【讨论】:

      • 我最终采用了与此非常相似的解决方案。
      【解决方案3】:

      如何获取 sp_msforeachdb 的定义,并对其进行调整以适合您的目的?要获得定义,您可以运行它(先按 ctrl-T 将结果窗格置于文本模式):

      sp_helptext sp_msforeachdb
      

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

      【讨论】:

        【解决方案4】:

        我们的每个数据库服务器都包含一个“DBA”数据库,其中包含充满此类元数据的表。

        “数据库”表将保留服务器上所有数据库的列表,您可以放置​​标志列来指示数据库状态(实时、存档、系统等)。

        那么你的 SCRIPT 做的第一件事就是去你的 DBA 数据库获取它应该运行的所有数据库的列表。

        我们甚至有一个夜间维护脚本,可确保服务器上物理上的所有数据库也都输入到我们的“DBA.databases”表中,如果没有,则会提醒我们。 (因为在这个表中添加一行应该是手动的过程)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-11-07
          • 2011-07-19
          • 2011-04-28
          • 2011-02-01
          • 2010-12-24
          • 2010-10-20
          • 1970-01-01
          相关资源
          最近更新 更多