Ausführen von SQL für alle DBs auf einem Server


38

Ich habe einige Standard-SQL-Anweisungen, die ich für mehrere Datenbanken auf einem einzelnen Server ausführe, um Probleme zu diagnostizieren:

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

Wie kann ich dies für alle Datenbanken auf einem einzelnen Server ausführen? (Neben dem manuellen Herstellen einer Verbindung zu einem bestimmten Zeitpunkt und dem Ausführen)


Sie können diese Alternative von ms_foreachdb auch nützlich finden.
Nomad

Antworten:


44

sp_MSForEachDB

Eine Option ist sp_MSForEachDB . Es ist undokumentiert, aber dennoch nützlich

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

Eine Suche in den Interwebs hat auch viele weitere Beispiele

Hinweis: Da es sich um eine nicht unterstützte Funktion handelt (die einige bekannte Fehler aufweist), möchten Sie möglicherweise Ihre eigene Version schreiben (danke @Pradeep).


Das obige SQL-Beispiel müsste folgendermaßen umstrukturiert werden:

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

ANMERKUNGEN:

  1. ? wird in der Abfrage als Datenbankname ersetzt. Strukturieren Sie die Abfrage, um explizit zu definieren, für welchen DB sie abgefragt werden soll
  2. geändert, um sys.all_sql_modules als vollständigen Modultext zu verwenden (syscomments könnte das Schlüsselwort aufteilen, wenn es über mehrere Zeilen reicht)

sp_MSforeachdb kann manchmal flockig sein, schauen Sie sich also den Link in Pradeeps Antwort an.
Eric Humphrey - Lotsahelp

Die sp_MSForEachDB scheint für eine schnelle Abfrage gut zu sein. Kann ich damit anzeigen, aus welcher Datenbank die einzelnen Ergebnisse stammen?
Festplatte

@Diskdrive: Zu , ''?'' AS DBNameeiner beliebigen Select-Anweisung hinzufügen . Nach meinem Beispiel
gbn

9

Nur meine $ 0.05: SQL Multi Script (Ausführung mehrerer Skripte gegen mehrere SQL Server).


1
Antworten wie diese, die eine kommerzielle Lösung befürworten, sollten SO verboten werden!
Fandango68

2
@ Fandango68 Ich arbeite nicht für diese Firma. Ich habe gerade so ein Werkzeug benutzt. Kein Interessenkonflikt, was ist mit dir? ).
Garik

4
@Fandango68 ich würde sie lieber nicht. Die besten Lösungen sollten immer in Betracht gezogen und die besten kostenlosen Lösungen dagegen abgewogen werden.
Paul


2

Es gibt eine weitere Methode, die eine Ausgabe in einer einzelnen, halb zusammengeführten Ergebnismenge liefert. Öffnen Sie zuerst Registrierte Server und erstellen Sie eine neue Gruppe unter Lokale Servergruppen. Registrieren Sie dann Ihren Server einmal für jede Datenbank und setzen Sie die Standard-Datenbank jeweils auf die gewünschte.

Wenn Sie fertig sind, klicken Sie mit der rechten Maustaste auf Ihre Gruppe und wählen Sie Neue Abfrage. Das sich öffnende Abfragefenster hat "mehrere", in denen normalerweise ein Servername in der Statusleiste angezeigt wird. Alle in diesem Fenster ausgeführten Abfragen werden auf jedem registrierten Server ausgeführt, der sich in der Gruppe befand. Die erste Spalte der Ergebnisse ist der Name des registrierten Servers. Die Ergebnismenge wird durch diese erste Spalte fragmentiert, und die Reihenfolge der Testamente wird nur innerhalb dieses Fragments ausgeführt.

Sehr leistungsstarke, aber übersehene Funktionalität für den Fall, dass Sie routinemäßig dasselbe SQL auf mehreren Servern ausführen müssen.


Ich benutze dies oft und es ist eine großartige Funktion in SSMS. Der Nachteil ist, dass es nur für den manuellen Gebrauch gedacht ist. Daher ist es nicht nützlich, wenn Sie etwas automatisieren möchten, das regelmäßig ausgeführt wird.
Sir Swears-a-lot


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.