Wie kann ich in SQL Server 2008 Express eine SQL Server-Datenbank auf demselben Server klonen?

271

Ich habe ein MS SQL Server 2008 Express-System, das eine Datenbank enthält, die ich (zu Testzwecken) kopieren und umbenennen möchte, aber mir ist kein einfacher Weg bekannt, dies zu erreichen.

Ich stelle fest, dass es in der R2-Version von SQL Server einen Assistenten zum Kopieren von Datenbanken gibt, aber leider kann ich kein Upgrade durchführen.

Bei der fraglichen Datenbank handelt es sich um einen Gig. Ich habe versucht, eine Sicherung der Datenbank wiederherzustellen, die ich in eine neue Datenbank kopieren möchte, aber ohne Glück.

Sergio
quelle
2
Das Wiederherstellen einer Sicherung sollte funktionieren. Können Sie näher erläutern, wie dies fehlgeschlagen ist?
Ed Harper
7
Mir wurde klar, dass ich beim Wiederherstellen aus dem Backup einen Fehler gemacht habe. Ich habe zuerst eine neue leere Datenbank erstellt und versucht, die Sicherung von dort wiederherzustellen. Ich hätte den Wiederherstellungsdialog aufrufen und dort den Namen der neuen Datenbank eingeben sollen, anstatt sie zuerst zu erstellen. Dadurch wurde die Datenbank gut geklont!
Sergio

Antworten:

372
  1. Installieren Sie Microsoft SQL Management Studio, das Sie kostenlos von der Microsoft-Website herunterladen können:

    Version 2008

    Microsoft SQL Management Studio 2008 ist Teil von SQL Server 2008 Express mit erweiterten Diensten

    Version 2012

    Klicken Sie auf die Schaltfläche Herunterladen und überprüfen SieENU\x64\SQLManagementStudio_x64_ENU.exe

    Version 2014

    Klicken Sie auf die Schaltfläche Herunterladen und überprüfen Sie MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. Öffnen Sie Microsoft SQL Management Studio .

  3. Sichern Sie die Originaldatenbank in einer .BAK-Datei (db -> Task -> Backup).
  4. Erstellen Sie eine leere Datenbank mit neuem Namen (Klon). Beachten Sie die folgenden Kommentare, da dies optional ist.
  5. Klicken Sie hier, um die Datenbank zu klonen und den Wiederherstellungsdialog zu öffnen (siehe Bild). Dialog wiederherstellen
  6. Wählen Sie Gerät und fügen Sie die Sicherungsdatei aus Schritt 3 hinzu. Sicherungsdatei hinzufügen
  7. Ändern Sie das Ziel in die Testdatenbank verändere das Ziel
  8. Ändern Sie den Speicherort der Datenbankdateien. Er muss sich vom Original unterscheiden. Sie können direkt in das Textfeld eingeben, indem Sie einfach Postfix hinzufügen. (HINWEIS: Die Reihenfolge ist wichtig. Aktivieren Sie das Kontrollkästchen und ändern Sie die Dateinamen.) den Ort wechseln
  9. Überprüfen Sie WITH REPLACE und WITH KEEP_REPLICATION mit ersetzen
Tomas Kubes
quelle
84
1. Erstellen Sie keine leere Datenbank und stellen Sie die .bak-Datei darauf wieder her. 2. Verwenden Sie die Option 'Datenbank wiederherstellen', auf die Sie zugreifen können, indem Sie mit der rechten Maustaste auf den Zweig "Datenbanken" des SQL Server Management Studio klicken, und geben Sie den Datenbanknamen an, während Sie die Quelle für die Wiederherstellung angeben. ref: stackoverflow.com/questions/10204480/…
taynguyen
1
Microsoft SQL Management Studio - es ist kostenlos
Tomas Kubes
4
Funktioniert nicht - "Exklusiver Zugriff konnte nicht erhalten werden, da die Datenbank verwendet wird".
Emanuele Ciriachi
5
Ich musste auch das Kontrollkästchen "Tail-Log-Backup vor der Wiederherstellung erstellen" deaktivieren. Dies wurde standardmäßig überprüft und führte zu dem Fehler "Exklusiver Zugriff konnte nicht erhalten werden, weil die Datenbank verwendet wird".
Rübe
2
Meine ursprüngliche Datenbank blieb bei "Restoring"
Divi perdomo
113

Rechtsklick auf die Datenbank zu klonen, klicken Tasks, klicken Sie auf Copy Database.... Folgen Sie dem Assistenten und Sie sind fertig.

DForck42
quelle
Ich denke, das ist leider nur in der R2-Version von SQL Server verfügbar :-(
Sergio
7
So funktioniert es im Express: stackoverflow.com/questions/4269450/…
Do 00 mÄ s
2
Dies funktioniert nicht, wenn Sie Objekte in Ihrer Datenbank verschlüsselt haben.
CJBarth
1
Ich würde sagen, dass der Hauptpunkt tatsächlich ist, wo es zu tun ist? Was Sie beschrieben haben, ist ziemlich intuitiv. Ich habe genau das in einigen Tools (0xDBE, Visual Studio SQL Server-Objekt-Explorer) versucht, aber dort keine solche Funktion gefunden.
David Ferenczy Rogožan
3
Nicht möglich! Aufgaben -> Kein Menüpunkt zum Kopieren der Datenbank
Raiserle
95

Sie können versuchen, die Datenbank zu trennen, die Dateien an einer Eingabeaufforderung in neue Namen zu kopieren und dann beide DBs anzuhängen.

In SQL:

USE master;
GO 
EXEC sp_detach_db
    @dbname = N'OriginalDB';
GO

An der Eingabeaufforderung (Ich habe die Dateipfade für dieses Beispiel vereinfacht):

copy c:\OriginalDB.mdf c:\NewDB.mdf
copy c:\OriginalDB.ldf c:\NewDB.ldf

Wieder in SQL:

USE master;
GO
CREATE DATABASE OriginalDB
    ON (FILENAME = 'C:\OriginalDB.mdf'),
       (FILENAME = 'C:\OriginalDB.ldf')
    FOR ATTACH;
GO
CREATE DATABASE NewDB
    ON (FILENAME = 'C:\NewDB.mdf'),
       (FILENAME = 'C:\NewDB.ldf')
    FOR ATTACH;
GO
Joe Stefanelli
quelle
1
perfekt! Dies ist die einzigartige Lösung, die für mich funktioniert hat! Vielen Dank!
Thiagoh
9
select * from OriginalDB.sys.sysfilesum den Speicherort der DB-Dateien zu finden.
JohnLBevan
Ja, ich mag diese Lösung auch am meisten, da sie keine speziellen Werkzeuge erfordert. Aber ich konnte keine NewDB erstellen, heißt es Permission deniedin der .mdfDatei. Ich brauche es jetzt nicht, ich brauchte nur eine Sicherung der ursprünglichen Datenbank, damit ich die ursprüngliche Datenbank später damit überschreiben kann. Ich bin nur neugierig, warum ich einen solchen Fehler erhalte.
David Ferenczy Rogožan
2
Sie müssen die ursprüngliche Datenbank nicht trennen, wenn Sie den SQL-Dienst stoppen, die MDF- und LDF-Datei kopieren, sie für Ihre neue Datenbank umbenennen, den SQL-Dienst erneut starten und einfach den letzten Befehl zum Erstellen einer Datenbank unter master: USE master ausführen können ;; GO CREATE DATABASE NewDB ON (FILENAME = 'C: \ NewDB.mdf'), (FILENAME = 'C: \ NewDB.ldf') FOR ATTACH; GO
Danpop
1
+1 für den schnellsten Weg. Zusätzlich zu @JohnLBevan ausgezeichneten Kommentar können Sie auch verwendenexec sp_helpdb @dbname='TEMPDB';
Jean
30

Es stellt sich heraus, dass ich versucht habe, aus einem Backup falsch wiederherzustellen.

Zunächst habe ich eine neue Datenbank erstellt und dann versucht, das Backup hier wiederherzustellen. Was ich hätte tun sollen und was am Ende funktioniert hat, war, den Wiederherstellungsdialog aufzurufen und den Namen der neuen Datenbank in das Zielfeld einzugeben.

Kurz gesagt, das Wiederherstellen von einem Backup hat den Trick getan.

Vielen Dank für alle Rückmeldungen und Vorschläge Jungs

Sergio
quelle
Wenn ich dies tue, sagt mir das Dialogfeld, dass sich die Dateien am selben Speicherort befinden wie die Datenbank, aus der ich ursprünglich gesichert habe. Ich habe also nicht den Mut, sie wiederherzustellen, weil ich befürchte, dass die Dateien überschrieben werden.
Niels Brinch
2
Neils, die Dateien sind in dem von Ihnen aufgenommenen Schnappschuss standardmäßig identisch. Sie können ihre Namen ändern, um neue Dateien für die neu benannte Datenbank zu erstellen.
Colin Dabritz
PS: Für diese Methode ist ein SQL Agent-Dienst erforderlich. Stellen Sie sicher, dass er ausgeführt wird, bevor Sie den DB-Kopiervorgang starten.
DVD
Sie haben mir jetzt dreimal mit dieser Antwort geholfen. Ich vergesse immer wieder, es einzutippen, anstatt es zu erstellen. + Bier
Piotr Kula
Dies und das Umbenennen der .mdf- und .log-Dateien im Fenster 'Dateien' haben bei mir funktioniert.
Wollan
17

Dies ist das Skript, das ich benutze. Ein bisschen knifflig, aber es funktioniert. Getestet auf SQL Server 2012.

DECLARE @backupPath nvarchar(400);
DECLARE @sourceDb nvarchar(50);
DECLARE @sourceDb_log nvarchar(50);
DECLARE @destDb nvarchar(50);
DECLARE @destMdf nvarchar(100);
DECLARE @destLdf nvarchar(100);
DECLARE @sqlServerDbFolder nvarchar(100);

SET @sourceDb = 'db1'
SET @sourceDb_log = @sourceDb + '_log'
SET @backupPath = 'E:\tmp\' + sourceDb + '.bak' --ATTENTION: file must already exist and SQL Server must have access to it
SET @sqlServerDbFolder = 'E:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\DATA\'
SET @destDb = 'db2'
SET @destMdf = @sqlServerDbFolder + @destDb + '.mdf'
SET @destLdf = @sqlServerDbFolder + @destDb + '_log' + '.ldf'

BACKUP DATABASE @sourceDb TO DISK = @backupPath

RESTORE DATABASE @destDb FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDb     TO @destMdf,
   MOVE @sourceDb_log TO @destLdf
bläulich
quelle
2
In meiner Umgebung stimmten die Dateinamen nicht mit dem Datenbanknamen überein (der von einer anderen Wiederherstellung stammt), daher benötigte ich SET @sourceDb_log = (SELECT files.name FROM sys.databases dbs INNER JOIN sys.master_files files ON dbs.database_id=files.database_id WHERE dbs.name=@sourceDb AND files.type=1)eine separate Variable für @sourceDb_data mit einer ähnlichen Abfrage (Ersetzen durch files.type=0). HTH!
Dan Caseley
11

Keine der hier genannten Lösungen hat bei mir funktioniert - ich verwende SQL Server Management Studio 2014.

Stattdessen musste ich das Kontrollkästchen "Tail-Log-Sicherung vor Wiederherstellung durchführen" im Bildschirm "Optionen" deaktivieren: In meiner Version ist es standardmäßig aktiviert und verhindert, dass der Wiederherstellungsvorgang abgeschlossen wird. Nach dem Deaktivieren wurde der Wiederherstellungsvorgang ohne Probleme fortgesetzt.

Geben Sie hier die Bildbeschreibung ein

Emanuele Ciriachi
quelle
2
Diese Antwort hat mir den Tag gerettet.
Dilhan Jayathilake
2
Ich habe auch meinen Tag gerettet :)
Ashilon
1
Wenn Sie dies mit SQL Server 2017 nicht tun, blieb die ursprüngliche Datenbank in "Wiederherstellen ...". Ihre Lösung hat es geschafft - danke!
Mu88
9

Mit MS SQL Server 2012 müssen Sie drei grundlegende Schritte ausführen:

  1. Generieren Sie zunächst eine .sqlDatei, die nur die Struktur der Quelldatenbank enthält

    • Klicken Sie mit der rechten Maustaste auf die Quelldatenbank und dann auf Aufgaben und dann auf Skripte generieren
    • Folgen Sie dem Assistenten und speichern Sie die .sqlDatei lokal
  2. Zweitens ersetzen Sie die Quell-DB durch die Ziel-DB in der .sqlDatei

    • Klicken Sie mit der rechten Maustaste auf die Zieldatei, wählen Sie Neue Abfrage und Ctrl-Hoder ( Bearbeiten - Suchen und Ersetzen - Schnelles Ersetzen )
  3. Zum Schluss füllen Sie mit Daten

    • Klicken Sie mit der rechten Maustaste auf die Ziel-DB und wählen Sie Aufgaben und Daten importieren
    • Datenquellen-Dropdown-Liste auf " .net Framework-Datenprovider für SQL Server " + Setzen Sie das Textfeld für die Verbindungszeichenfolge unter DATA, z.Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • Machen Sie dasselbe mit dem Ziel
    • Aktivieren Sie die Tabelle, die Sie übertragen möchten, oder aktivieren Sie das Kontrollkästchen neben "Quelle: ...", um alle zu aktivieren

Du bist fertig.

Mehdi Benkirane
quelle
Übrigens, ich denke, Importdaten können Tabellen erstellen, wenn sie nicht in Zieltabellen vorhanden sind. Einfache Lösung +1
Khurram Ishaque
6

Sichern Sie in SQL Server 2008 R2 die Datenbank als Datei in einem Ordner. Wählen Sie dann die Wiederherstellungsoption, die im Ordner "Datenbank" angezeigt wird. Geben Sie im Assistenten den gewünschten neuen Namen in die Zieldatenbank ein. Wählen Sie "Aus Datei wiederherstellen" und verwenden Sie die gerade erstellte Datei. Ich habe es nur getan und es war sehr schnell (meine DB war klein, aber immer noch) Pablo.

pabloelustondo
quelle
4

Wenn die Datenbank nicht sehr groß ist, können Sie die Befehle "Skriptdatenbank" in SQL Server Management Studio Express anzeigen, die sich in einem Kontextmenü neben dem Datenbankelement selbst im Explorer befinden.

Sie können auswählen, was alles geschrieben werden soll. Sie wollen natürlich die Objekte und die Daten. Anschließend speichern Sie das gesamte Skript in einer einzigen Datei. Anschließend können Sie diese Datei verwenden, um die Datenbank neu zu erstellen. Stellen Sie einfach sicher, dass der USEBefehl oben auf die richtige Datenbank eingestellt ist.

Andrew Barber
quelle
1
Danke, die Datenbank ist jedoch ziemlich groß (um einen Auftritt herum), also denke ich, dass schlimme Dinge passieren können :-)
Sergio
2
Richtig; das ist dann nicht der beste Weg. Stattdessen können Sie die Skriptdatenbank verwenden, um nur die Struktur in der neuen Datenbank zu erstellen, und dann Importieren / Exportieren, um die Daten zu verschieben. Stellen Sie nur sicher, dass Sie zuerst die Skriptdatenbank erstellen. Beim Importieren / Exportieren werden die Tabellen erstellt, wenn sie nicht vorhanden sind, und Sie mögen möglicherweise nicht, wie es funktioniert.
Andrew Barber
4

Die Lösung basiert auf diesem Kommentar: https://stackoverflow.com/a/22409447/2399045 . Stellen Sie einfach die Einstellungen ein: DB-Name, temporärer Ordner, Ordner mit DB-Dateien. Und nach dem Ausführen haben Sie die Kopie der Datenbank mit dem Namen "sourceDBName_yyyy-mm-dd".

-- Settings --
-- New DB name will have name = sourceDB_yyyy-mm-dd
declare @sourceDbName nvarchar(50) = 'MyDbName';
declare @tmpFolder nvarchar(50) = 'C:\Temp\'
declare @sqlServerDbFolder nvarchar(100) = 'C:\Databases\'

--  Execution --
declare @sourceDbFile nvarchar(50);
declare @sourceDbFileLog nvarchar(50);
declare @destinationDbName nvarchar(50) = @sourceDbName + '_' + (select convert(varchar(10),getdate(), 121))
declare @backupPath nvarchar(400) = @tmpFolder + @destinationDbName + '.bak'
declare @destMdf nvarchar(100) = @sqlServerDbFolder + @destinationDbName + '.mdf'
declare @destLdf nvarchar(100) = @sqlServerDbFolder + @destinationDbName + '_log' + '.ldf'

SET @sourceDbFile = (SELECT top 1 files.name 
                    FROM sys.databases dbs 
                    INNER JOIN sys.master_files files 
                        ON dbs.database_id = files.database_id 
                    WHERE dbs.name = @sourceDbName
                        AND files.[type] = 0)

SET @sourceDbFileLog = (SELECT top 1 files.name 
                    FROM sys.databases dbs 
                    INNER JOIN sys.master_files files 
                        ON dbs.database_id = files.database_id 
                    WHERE dbs.name = @sourceDbName
                        AND files.[type] = 1)

BACKUP DATABASE @sourceDbName TO DISK = @backupPath

RESTORE DATABASE @destinationDbName FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDbFile     TO @destMdf,
   MOVE @sourceDbFileLog  TO @destLdf
Pavel Samoylenko
quelle
3

Skript basierend auf Joe Antwort ( Dateien trennen, kopieren, beide anhängen ).

  1. Führen Sie Managment Studio als Administratorkonto aus.

Es ist nicht notwendig, aber möglicherweise wird der Fehler beim Ausführen verweigert.

  1. Konfigurieren Sie den SQL Server für die Ausführung von xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Führen Sie das Skript aus, geben Sie jedoch zuvor Ihre Datenbanknamen @dbNameund @copyDBNameVariablen ein.
USE master;
GO 

DECLARE @dbName NVARCHAR(255) = 'Products'
DECLARE @copyDBName NVARCHAR(255) = 'Products_branch'

-- get DB files
CREATE TABLE ##DBFileNames([FileName] NVARCHAR(255))
EXEC('
    INSERT INTO ##DBFileNames([FileName])
    SELECT [filename] FROM ' + @dbName + '.sys.sysfiles')

-- drop connections
EXEC('ALTER DATABASE ' + @dbName + ' SET OFFLINE WITH ROLLBACK IMMEDIATE')

EXEC('ALTER DATABASE ' + @dbName + ' SET SINGLE_USER')

-- detach
EXEC('EXEC sp_detach_db @dbname = ''' + @dbName + '''')

-- copy files
DECLARE @filename NVARCHAR(255), @path NVARCHAR(255), @ext NVARCHAR(255), @copyFileName NVARCHAR(255), @command NVARCHAR(MAX) = ''
DECLARE 
    @oldAttachCommand NVARCHAR(MAX) = 
        'CREATE DATABASE ' + @dbName + ' ON ', 
    @newAttachCommand NVARCHAR(MAX) = 
        'CREATE DATABASE ' + @copyDBName + ' ON '

DECLARE curs CURSOR FOR 
SELECT [filename] FROM ##DBFileNames
OPEN curs  
FETCH NEXT FROM curs INTO @filename
WHILE @@FETCH_STATUS = 0  
BEGIN
    SET @path = REVERSE(RIGHT(REVERSE(@filename),(LEN(@filename)-CHARINDEX('\', REVERSE(@filename),1))+1))
    SET @ext = RIGHT(@filename,4)
    SET @copyFileName = @path + @copyDBName + @ext

    SET @command = 'EXEC master..xp_cmdshell ''COPY "' + @filename + '" "' + @copyFileName + '"'''
    PRINT @command
    EXEC(@command);

    SET @oldAttachCommand = @oldAttachCommand + '(FILENAME = "' + @filename + '"),'
    SET @newAttachCommand = @newAttachCommand + '(FILENAME = "' + @copyFileName + '"),'

    FETCH NEXT FROM curs INTO @filename
END
CLOSE curs 
DEALLOCATE curs

-- attach
SET @oldAttachCommand = LEFT(@oldAttachCommand, LEN(@oldAttachCommand) - 1) + ' FOR ATTACH'
SET @newAttachCommand = LEFT(@newAttachCommand, LEN(@newAttachCommand) - 1) + ' FOR ATTACH'

-- attach old db
PRINT @oldAttachCommand
EXEC(@oldAttachCommand)

-- attach copy db
PRINT @newAttachCommand
EXEC(@newAttachCommand)

DROP TABLE ##DBFileNames
Evgeny Ivanov
quelle
3

Sie können einfach eine neue Datenbank erstellen und dann zu Aufgaben gehen, Daten importieren und alle Daten aus der Datenbank importieren, die Sie in die gerade erstellte Datenbank duplizieren möchten.

Techie Philosoph
quelle
2

Eine andere Möglichkeit, die den Trick mithilfe des Import / Export-Assistenten ausführt , zuerst eine leere Datenbank zu erstellen, dann die Quelle auszuwählen, die Ihr Server mit der Quellendatenbank ist, und dann im Ziel denselben Server mit der Zieldatenbank auszuwählen (mithilfe der leeren Datenbank) Sie haben zuerst erstellt) und dann auf Fertig stellen geklickt

Es werden alle Tabellen erstellt und alle Daten in die neue Datenbank übertragen.

Mohanad Kaleia
quelle