如何对服务器上的所有数据库执行SQL


38

我在单个服务器上针对多个数据库运行一些标准SQL,以帮助我诊断问题:

select 
    so.name,
    so.type,
    MAX(case when sc.text like '%remote%' then '' ELSE 'N' END) AS Relevant,
    @@ServerName as Server,
    DB_Name() as DBName 
from
    sysobjects so with (nolock)
    join syscomments sc with (nolock) on so.id = sc.id
where (sc.text like '%emote%')
group by so.name, so.type
order by so.type, so.name

如何在单个服务器上对所有数据库执行此操作?(除了手动连接到一个并执行)


您可能还会发现ms_foreachdb的这种替代方法也很有用。
Nomad

Answers:


44

sp_MSForEachDB

一种选择是sp_MSForEachDB。它没有记录,但仍然有用

DECLARE @command varchar(1000) 
SELECT @command = 
    'USE [?] UPDATE Table1 SET Field1 = ''ninjas'' WHERE Field2 = ''pirates''' 
EXEC sp_MSforeachdb @command

搜索互连网也有更多示例

注意:作为不受支持的功能(具有一些已知的错误),您可能需要编写自己的版本(感谢@Pradeep)


上面的SQL示例将需要重组为:

DECLARE @findKeySQL nvarchar(2000)
DECLARE @searchKey nvarchar(20)

SET @searchKey = lower('%remote%')

SET @findKeySQL = 'IF ''[?]'' NOT IN (''[master]'', ''[model]'', 
                                     ''[msdb]'', ''[tempdb]'')
        select 
            so.name,
            so.type,
            @@ServerName as Server,
            ''?'' as DBName 
        from
            [?].dbo.sysobjects so with (nolock)
            join [?].sys.all_sql_modules sc with (nolock) on so.id = sc.object_id
        where (lower(sc.definition) like ''' + @searchKey + ''')
        group by so.name, so.type
        order by so.type, so.name'

EXEC sp_MSForEachDB @findKeySQL

笔记:

  1. ?在查询中被替换为数据库名称,因此构造查询以显式定义要查询的数据库
  2. 修改为使用sys.all_sql_modules作为保存完整的模块文本(syscomments 可以在跨越行时拆分关键字)

sp_MSforeachdb有时可能会有些不稳定,因此请查看Pradeep的答案中提供的链接。
埃里克·汉弗莱

sp_MSForEachDB对于快速查询似乎很好。有没有一种方法可以显示每个结果来自哪个数据库?
Diskdrive

@Diskdrive:添加, ''?'' AS DBName到任何选择语句。根据我的示例
gbn

9

仅$ 0.05:SQL Multi Script(针对多个SQL Server执行多个脚本)。


1
这样的答案,赞成商业解决方案,应该被禁止!
Fandango68年

2
@ Fandango68我不在那家公司工作。我刚刚使用过这样的工具。没有利益冲突,那你呢?)。
加里克

4
@ Fandango68我希望他们不是。应该始终考虑最好的解决方案,并且最好的免费解决方案也要权衡它们。
保罗

3

SSMS Tools Pack可以很好地做到这一点,并且它对于2012年之前的数据库服务器是免费的。功能:“在多个目标上运行”-http://www.ssmstoolspack.com/Features?f =6


2

还有一种方法可以在单个半合并结果集中提供输出。首先打开“注册服务器”并在“本地服务器组”下创建一个新组,然后为每个数据库注册一次服务器,在每种情况下,将默认数据库设置为所需的数据库。

完成后,右键单击您的组,然后选择“新建查询”。打开的查询窗口将带有“多个”,您通常会在状态栏上看到服务器名称。在该窗口中运行的所有查询都将在组中每个已注册的服务器上运行。结果的第一列将是注册服务器的名称。结果集将由该第一列分段,而按遗嘱排序仅在该分段内操作。

当您通常必须在多个服务器上运行相同的SQL时,该功能非常强大,但却被忽略了。


我经常使用它,这在SSMS中是一个很棒的功能。缺点是它仅用于手动使用,因此如果您想自动化某些东西以使其定期运行,则没有用。
Swears-a-lot爵士'18


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.