我在哪里,我们有一个在大型机系统上运行的软件包。大型机每晚都会转储到sql server中,这样我们的每个客户端都在服务器中拥有自己的数据库。服务器实例中还有一些其他数据库,以及一些没有数据的旧客户端数据库。
我们经常需要在所有客户端上运行报告或检查数据。我希望能够使用sp_msforeachdb或类似的东西运行查询,但我不知道如何从列表中过滤掉不需要的dbs。有关这如何工作的任何想法?
我们仍然使用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
列,但除此之外它运行良好。
除非我今天得到另一个好主意,否则我希望将其转换为存储过程,并使用临时表将版本作为表值函数放在一起,将所有结果放在一个结果集中(仅适用于选择查询)
答案 0 :(得分:1)
只需将要执行的语句包装在IF NOT IN:
中EXEC sp_msforeachdb "
IF '?' NOT IN ('DBs','to','exclude') BEGIN
EXEC sp_whatever_you_want_to
END
"
答案 1 :(得分:0)
我们的每个数据库服务器都包含一个“DBA”数据库,其中包含完整的元数据表。
“数据库”表将保留服务器上所有数据库的列表,您可以放置标志列以指示数据库状态(实时,存档,系统等)。
然后你的SCRIPT做的第一件事就是去你的DBA数据库获取它应该运行的所有数据库的列表。
我们甚至还有一个夜间维护脚本,可确保服务器上物理上的所有数据库也输入到我们的“DBA.databases”表中,如果不是,则会提醒我们。 (因为在此表中添加一行应该是一个手动过程)
答案 2 :(得分:0)
如何获取sp_msforeachdb的定义并调整它以适合您的目的?要获得定义,您可以运行此命令(首先按ctrl-T将结果窗格置于文本模式):
sp_helptext sp_msforeachdb
显然你会想要创建自己的这个sproc版本而不是覆盖原始版本; o)
答案 3 :(得分:0)
在2005 SSIS包中做这种事情非常简单。也许您可以在某个服务器上设置实例。
我们设置了多个服务器,因此我们有一个表格,表示将调查哪些服务器。然后,我们撤回所有数据库的列表。这用于备份脚本。
您可以维护此数据库列表并添加一些字段以用于您自己的目的。您可以拥有另一个包或步骤,具体取决于您决定报告哪些数据库以及是否可以通过编程方式完成。
您可以在此免费获取代码:http://www.sqlmag.com/Articles/ArticleID/97840/97840.html?Ad=1
我们的系统基于此代码。