SQL Server - Kopieren Sie gespeicherte Prozeduren von einer Datenbank in eine andere

85

Ich bin neu in SQL, und ich musste 2 MDF-Datenbanken zu einer kombinieren. Ich habe das mit SQL Server 2008 Manager gemacht - Aufgaben> Tabellen importieren / exportieren. Die Tabellen und Ansichten wurden erfolgreich kopiert, aber es gibt keine gespeicherten Prozeduren in der neuen Datenbank. Gibt es eine Möglichkeit, das zu tun?

Eiche
quelle
1
Wenn Sie sie programmgesteuert kopieren möchten, beginnen Sie hier: stackoverflow.com/a/6124487/138938
Jon Crowell

Antworten:

136
  • Klicken Sie mit der rechten Maustaste auf die Datenbank
  • Aufgaben
  • Skripte generieren
  • Wählen Sie die Objekte aus, die Sie skripten möchten
  • Skript in Datei
  • Führen Sie generierte Skripte für die Zieldatenbank aus
Jaimal Chohan
quelle
Hallo, danke für die schnelle Antwort. Können Sie bitte erklären, wie ein Skript für die Zieldatenbank verwendet wird? Ich bin neu in diesem.
Eiche
1
@BarryKaye Was ist, wenn er 30-40 gespeicherte Prozeduren hat? Wäre das Klicken mit der rechten Maustaste nicht etwas langsam?
rvphx
@Oak Öffnen Sie die generierte Skriptdatei in SQL Management Studio. Ändern Sie die Verbindung zu Ihrer neuen Datenbank. Ändern Sie die Zeile ganz oben in der Datei, in der "Datenbankname verwenden" für Ihre Datenbank steht, und führen Sie sie aus.
Jaimal Chohan
Beeindruckend. Jetzt dachte ich, dass ich der einzige war, der einen GUI-basierten Ansatz mochte !!
rvphx
10
@RajivVarma - Sie erledigen diese Aufgabe einmal für die Datenbank - nicht für jeden SP! Wenn Sie das Kontrollkästchen der obersten Ebene neben "Gespeicherte Prozeduren" aktivieren, werden alle zusammen ausgewählt - 1 Klick.
Barry Kaye
19

Dieser Code kopiert alle in der Master-Datenbank gespeicherten Prozeduren in die Zieldatenbank. Sie können nur die gewünschten Prozeduren kopieren, indem Sie die Abfrage nach dem Prozedurnamen filtern.

@sql ist definiert als nvarchar (max), @Name ist die Zieldatenbank

DECLARE c CURSOR FOR 
   SELECT Definition
   FROM [ResiDazeMaster].[sys].[procedures] p
   INNER JOIN [ResiDazeMaster].sys.sql_modules m ON p.object_id = m.object_id

OPEN c

FETCH NEXT FROM c INTO @sql

WHILE @@FETCH_STATUS = 0 
BEGIN
   SET @sql = REPLACE(@sql,'''','''''')
   SET @sql = 'USE [' + @Name + ']; EXEC(''' + @sql + ''')'

   EXEC(@sql)

   FETCH NEXT FROM c INTO @sql
END             

CLOSE c
DEALLOCATE c
ShaQue
quelle
Danke! ... In den Kommentaren, aber nicht im Code deklariert sind @sql& @Name:DECLARE @sql NVARCHAR(MAX); DECLARE @Name NVARCHAR(32);
datalifenyc
Gibt es eine Möglichkeit, dies auf verschiedenen Servern zu tun? Von Server A zu Server B?
Rajaram1991
5

Spät, gibt aber mehr Details, die nützlich sein könnten ...

Hier ist eine Liste von Dingen, die Sie mit Vor- und Nachteilen tun können

Generieren Sie Skripte mit SSMS

  • Vorteile: extrem einfach zu bedienen und standardmäßig unterstützt
  • Nachteile: Skripte befinden sich möglicherweise nicht in der richtigen Ausführungsreihenfolge und es können Fehler auftreten, wenn die gespeicherte Prozedur bereits in der sekundären Datenbank vorhanden ist. Stellen Sie sicher, dass Sie das Skript überprüfen, bevor Sie es ausführen.

Tools von Drittanbietern

  • Vorteile : Tools wie ApexSQL Diff (das ist, was ich benutze, aber es gibt viele andere wie Tools von Red Gate oder Dev Art) vergleichen zwei Datenbanken mit einem Klick und generieren ein Skript, das Sie sofort ausführen können
  • Nachteile: Diese sind nicht kostenlos (die meisten Anbieter haben jedoch eine voll funktionsfähige Testversion)

Systemansichten

  • Vorteile: Sie können leicht erkennen, welche gespeicherten Prozeduren auf dem sekundären Server vorhanden sind, und nur diejenigen generieren, die Sie nicht haben.
  • Nachteile: Erfordert etwas mehr SQL-Kenntnisse

Hier erfahren Sie, wie Sie eine Liste aller Prozeduren in einer Datenbank abrufen, die in einer anderen Datenbank nicht vorhanden sind

select *
from DB1.sys.procedures P
where P.name not in 
 (select name from DB2.sys.procedures P2)
LarryB
quelle
5

Ich habe diesen Beitrag ursprünglich auf der Suche nach einer Lösung zum Kopieren gespeicherter Prozeduren aus meiner Remote-Produktionsdatenbank in meine lokale Entwicklungsdatenbank gefunden. Nachdem ich den in diesem Thread vorgeschlagenen Ansatz erfolgreich angewendet hatte, stellte ich fest, dass ich zunehmend faul (oder einfallsreich, je nachdem, was Sie bevorzugen) wurde, und wollte, dass dies automatisiert wird. Ich bin auf diesen Link gestoßen, der sich als sehr hilfreich erwiesen hat (danke vincpa), und habe ihn erweitert, was zu der folgenden Datei führte (schema_backup.ps1):

$server             = "servername"
$database           = "databaseName"
$output_path        = "D:\prod_schema_backup"
$login = "username"
$password = "password"

$schema             = "dbo"
$table_path         = "$output_path\table\"
$storedProcs_path   = "$output_path\stp\"
$views_path         = "$output_path\view\"
$udfs_path          = "$output_path\udf\"
$textCatalog_path   = "$output_path\fulltextcat\"
$udtts_path         = "$output_path\udtt\"

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")  | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")  | out-null
$srvConn = new-object Microsoft.SqlServer.Management.Common.ServerConnection
$srvConn.ServerInstance = $server
$srvConn.LoginSecure = $false
$srvConn.Login = $login
$srvConn.Password = $password
$srv        = New-Object Microsoft.SqlServer.Management.SMO.Server($srvConn)
$db         = New-Object ("Microsoft.SqlServer.Management.SMO.Database")
$tbl        = New-Object ("Microsoft.SqlServer.Management.SMO.Table")
$scripter   = New-Object Microsoft.SqlServer.Management.SMO.Scripter($srvConn)

# Get the database and table objects
$db = $srv.Databases[$database]

$tbl            = $db.tables | Where-object { $_.schema -eq $schema  -and -not $_.IsSystemObject } 
$storedProcs    = $db.StoredProcedures | Where-object { $_.schema -eq $schema -and -not $_.IsSystemObject } 
$views          = $db.Views | Where-object { $_.schema -eq $schema } 
$udfs           = $db.UserDefinedFunctions | Where-object { $_.schema -eq $schema -and -not $_.IsSystemObject } 
$catlog         = $db.FullTextCatalogs
$udtts          = $db.UserDefinedTableTypes | Where-object { $_.schema -eq $schema } 

# Set scripter options to ensure only data is scripted
$scripter.Options.ScriptSchema  = $true;
$scripter.Options.ScriptData    = $false;

#Exclude GOs after every line
$scripter.Options.NoCommandTerminator   = $false;
$scripter.Options.ToFileOnly            = $true
$scripter.Options.AllowSystemObjects    = $false
$scripter.Options.Permissions           = $true
$scripter.Options.DriAllConstraints     = $true
$scripter.Options.SchemaQualify         = $true
$scripter.Options.AnsiFile              = $true

$scripter.Options.SchemaQualifyForeignKeysReferences = $true

$scripter.Options.Indexes               = $true
$scripter.Options.DriIndexes            = $true
$scripter.Options.DriClustered          = $true
$scripter.Options.DriNonClustered       = $true
$scripter.Options.NonClusteredIndexes   = $true
$scripter.Options.ClusteredIndexes      = $true
$scripter.Options.FullTextIndexes       = $true

$scripter.Options.EnforceScriptingOptions   = $true

function CopyObjectsToFiles($objects, $outDir) {
    #clear out before 
    Remove-Item $outDir* -Force -Recurse
    if (-not (Test-Path $outDir)) {
        [System.IO.Directory]::CreateDirectory($outDir)
    }   

    foreach ($o in $objects) { 

        if ($o -ne $null) {

            $schemaPrefix = ""

            if ($o.Schema -ne $null -and $o.Schema -ne "") {
                $schemaPrefix = $o.Schema + "."
            }

            #removed the next line so I can use the filename to drop the stored proc 
            #on the destination and recreate it
            #$scripter.Options.FileName = $outDir + $schemaPrefix + $o.Name + ".sql"
            $scripter.Options.FileName = $outDir + $schemaPrefix + $o.Name
            Write-Host "Writing " $scripter.Options.FileName
            $scripter.EnumScript($o)
        }
    }
}

# Output the scripts
CopyObjectsToFiles $tbl $table_path
CopyObjectsToFiles $storedProcs $storedProcs_path
CopyObjectsToFiles $views $views_path
CopyObjectsToFiles $catlog $textCatalog_path
CopyObjectsToFiles $udtts $udtts_path
CopyObjectsToFiles $udfs $udfs_path

Write-Host "Finished at" (Get-Date)
$srv.ConnectionContext.Disconnect()

Ich habe eine .bat-Datei, die dies aufruft und vom Taskplaner aufgerufen wird. Nach dem Aufruf der Powershell-Datei habe ich:

for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /Q "DROP PROCEDURE %f"

Diese Zeile geht durch das Verzeichnis und löscht die Prozeduren, die neu erstellt werden sollen. Wenn dies keine Entwicklungsumgebung wäre, möchte ich Prozeduren nicht programmgesteuert auf diese Weise löschen. Ich benenne dann alle gespeicherten Prozedurdateien um, um .sql zu haben:

powershell Dir d:\prod_schema_backup\stp\ | Rename-Item -NewName { $_.name + ".sql" }

Und dann laufen:

for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /E /i "%f".sql

Dadurch werden alle .sql-Dateien durchlaufen und die gespeicherten Prozeduren neu erstellt. Ich hoffe, dass sich irgendein Teil davon als hilfreich für jemanden erweisen wird.

vandsh
quelle
Ich mag das. Ich muss einen Prozess zum Archivieren von Chunks aus einer Produktions-DB jedes Jahr schreiben. Ich möchte nicht, dass SQL-Dateien hängen bleiben, die wahrscheinlich nicht aktualisiert werden, wenn sich das Schema entwickelt. Daher passe ich dies an, um eine leere Datenbank basierend auf einem Ziel zu erstellen, ohne den Zwischenschritt des Schreibens von Dateien auf die Festplatte (mehr) Aufräumen). Ich denke, dies ist wahrscheinlich die beste und am besten wiederverwendbare Antwort auf diese Frage, ein dickes Lob, Sir!
Steve Pettifer
3

Mit der SSMS-Funktion "Generate Scripts ..." können Sie alles ausschreiben, was Sie übertragen möchten. Klicken Sie mit der rechten Maustaste auf die Quellendatenbank in SSMS, wählen Sie "Skripte generieren ..." und folgen Sie dem Assistenten. Führen Sie dann Ihr resultierendes Skript aus, das jetzt die Anweisungen zum Erstellen der gespeicherten Prozedur enthält.

Bluevector
quelle
3

verwenden

select * from sys.procedures

um alle Ihre Verfahren zu zeigen;

sp_helptext @objname = 'Procedure_name'

um den Code zu bekommen

und deine Kreativität, etwas zu bauen, um sie alle zu durchlaufen und den Exportcode zu generieren :)

Diego
quelle
3

Sie können ein Skript für die gespeicherten Prozesse erstellen, wie in anderen Antworten dargestellt. Sobald das Skript generiert wurde, können Sie es sqlcmdfür Ziel-DB wie ausführen

sqlcmd -S <server name> -U <user name> -d <DB name> -i <script file> -o <output log file> 
Rahul
quelle
0

Klicken Sie in Mgmt Studio mit der rechten Maustaste auf Ihre ursprüngliche Datenbank, dann auf Aufgaben und dann auf Skripte generieren ... - Folgen Sie dem Assistenten.

Barry Kaye
quelle
0

SELECT-Definition + char (13) + 'GO' FROM MyDatabase.sys.sql_modules s INNER JOIN MyDatabase.sys.procedures p ON [s]. [Object_id] = [p]. [Object_id] WHERE p.name LIKE 'Something% '"queryout" c: \ SP_scripts.sql -S MyInstance -T -t -w

Holen Sie sich die SP und führen Sie es aus

ShaQue
quelle
Dies ist eine sehr schöne Lösung, aber 1) Sie sollten darauf hinweisen, dass eine Text- oder Dateiausgabe erforderlich ist (zeigen Sie die Ergebnisse nicht im Raster an, sonst verlieren Sie EOL-Zeichen) und 2) es scheint ein Limit von 8 KB zu geben für die Textausgabe in SQL Server Management Studio.
DAB
0

Eine weitere Option ist das Übertragen gespeicherter Prozeduren mit SQL Server Integration Services (SSIS) . Es gibt eine Aufgabe namens SQL Server-Objektaufgabe übertragen . Mit der Aufgabe können Sie folgende Elemente übertragen:

  • Tabellen
  • Ansichten
  • Gespeicherte Prozeduren
  • Benutzerdefinierte Funktionen
  • Standardeinstellungen
  • Benutzerdefinierte Datentypen
  • Partitionsfunktionen
  • Partitionsschemata
  • Schemata
  • Baugruppen
  • Benutzerdefinierte Aggregate
  • Benutzerdefinierte Typen
  • XML-Schemasammlung

Es ist ein grafisches Tutorial für die Aufgabe "SQL Server-Objekte übertragen".

Abdollah
quelle