サーバー上のすべてのDBに対して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

単一サーバー上のすべてのデータベースに対してこれを実行するにはどうすればよいですか?(手動で1つずつ接続して実行することに加えて)


ms_foreachdbのこの代替手段も有用であることがわかります。
ノマド

回答:


44

sp_MSForEachDB

1つのオプションは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. ?クエリではデータベース名として置き換えられるため、クエリを構成して、クエリ対象のDBを明示的に定義します
  2. 完全なモジュールテキストを保持するsys.all_sql_modulesを使用するように変更(syscomments は行にまたがるときにキーワードを分割できます)

sp_MSforeachdbは時々不安定になる可能性があるため、Pradeepの回答に記載されているリンクを参照してください。
エリックハンフリー-lotsahelp

sp_MSForEachDBは、簡単なクエリに適しているようです。それぞれの結果がどのデータベースから来たのかを表示する方法はありますか?
ディスクドライブ

@Diskdrive:, ''?'' AS DBName選択ステートメントに追加します。私の例のように
GBN

9

ちょうど私の$ 0.05:SQL Multi Script(複数のSQL Serverに対する複数のスクリプトの実行)。


1
商用ソリューションを推奨するこのような回答は、禁止する必要があります!
ファンダンゴ

2
@ Fandango68私はその会社で働いていません。ツールを使用しました。利益相反はありません、あなたはどうですか?)。
ガリック

4
@ Fandango68私はむしろそうではありませんでした。最良のソリューションは常に考慮されるべきであり、最良の無料ソリューションはそれらと比較検討されました。
ポール

3

SSMS Tools Packはこれをうまく行い、2012年より前のデータベースサーバーでは無料です。機能:「複数のターゲットで実行」-http://www.ssmstoolspack.com/Features?f =6


2

単一の半マージされた結果セットで出力する別の方法があります。最初に「登録済みサーバー」を開き、「ローカルサーバーグループ」の下に新しいグループを作成してから、各DBに対してサーバーを1回登録します。それぞれの場合、デフォルトDBを目的のDBに設定します。

完了したら、グループを右クリックして、[新しいクエリ]を選択します。開くクエリウィンドウには、通常、ステータスバーにサーバー名が表示される「複数」があります。このウィンドウで実行されるクエリは、グループ内にあった登録済みの各サーバーで実行されます。結果の最初の列は、登録済みサーバーの名前になります。結果セットはその最初の列によってフラグメント化され、order by willはそのフラグメント内でのみ動作します。

非常に強力ですが、複数のサーバーで同じSQLを定期的に実行する必要がある場合に見落とされがちな機能。


私はこれを頻繁に使用し、SSMSの優れた機能です。欠点は、手動での使用のみであるため、定期的に実行するために何かを自動化する場合は役に立たないことです。
サー・スウェアーズ・ロット


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.