Come posso clonare un database SQL Server sullo stesso server in SQL Server 2008 Express?


272

Ho un sistema MS SQL Server 2008 Express che contiene un database che vorrei "copiare e rinominare" (a scopo di test) ma non sono a conoscenza di un modo semplice per raggiungere questo obiettivo.

Ho notato che nella versione R2 di SQL Server esiste una procedura guidata per la copia del database, ma purtroppo non riesco ad aggiornare.

Il database in questione è intorno a un concerto. Ho provato a ripristinare un backup del database che voglio copiare in un nuovo database, ma senza fortuna.


2
Il ripristino di un backup dovrebbe funzionare. Potete fornire maggiori dettagli su come ciò è fallito?
Ed Harper,

7
Mi sono reso conto di aver fatto un errore durante il ripristino dal backup. Ho creato prima un nuovo DB vuoto e ho tentato di ripristinare il backup da lì. Quello che avrei dovuto fare è far apparire la finestra di ripristino e digitare il nome del nuovo database lì dentro invece di crearlo prima. In questo modo clonato bene il database!
Sergio,

Risposte:


372
  1. Installa Microsoft SQL Management Studio, che puoi scaricare gratuitamente dal sito Web di Microsoft:

    Versione 2008

    Microsoft SQL Management Studio 2008 fa parte di SQL Server 2008 Express con servizi avanzati

    Versione 2012

    Fai clic sul pulsante Scarica e selezionaENU\x64\SQLManagementStudio_x64_ENU.exe

    Versione 2014

    Fare clic sul pulsante Scarica e selezionare MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. Apri Microsoft SQL Management Studio .

  3. Eseguire il backup del database originale nel file .BAK (db -> Attività -> Backup).
  4. Crea database vuoto con nuovo nome (clone). Nota i commenti qui sotto in quanto questo è facoltativo.
  5. Fare clic per clonare il database e aprire la finestra di dialogo di ripristino (vedere l'immagine) finestra di dialogo di ripristino
  6. Seleziona Dispositivo e aggiungi il file di backup dal passaggio 3. aggiungi file di backup
  7. Cambia destinazione per testare il database Cambiare la destinazione
  8. Cambia posizione dei file del database, deve essere diverso dall'originale. Puoi digitare direttamente nella casella di testo, basta aggiungere postfix. (NOTA: l'ordine è importante. Selezionare la casella di controllo, quindi modificare i nomi dei file.) Cambia posizione
  9. Seleziona WITH REPLACE e WITH KEEP_REPLICATION con sostituire

84
1. Non creare un database vuoto e ripristinare il file .bak su di esso. 2. Utilizzare l'opzione "Ripristina database" accessibile facendo clic con il pulsante destro del mouse sul ramo "Database" di SQL Server Management Studio e fornire il nome del database fornendo al contempo l'origine da ripristinare. ref: stackoverflow.com/questions/10204480/...
taynguyen

1
Microsoft SQL Management Studio - è gratuito
Tomas Kubes

4
Non funziona: "Impossibile ottenere l'accesso esclusivo perché il database è in uso".
Emanuele Ciriachi,

5
Ho anche dovuto deselezionare "Esegui backup del registro di coda prima del ripristino". Questo è stato verificato per impostazione predefinita e ha provocato l'errore "Impossibile ottenere l'accesso esclusivo perché il database è in uso".
Rapa,

3
Il mio database originale si è bloccato su "Ripristino"
Divi perdomo

114

Fare clic con il tasto destro del mouse sul database per clonare, fare clic Tasks, fare clic Copy Database.... Segui la procedura guidata e il gioco è fatto.


Penso che sia disponibile solo nella versione R2 di SQL Server :-(
Sergio,

7
ecco come funziona in express: stackoverflow.com/questions/4269450/…
Th 00

2
Questo non funziona se hai oggetti crittografati nel tuo database.
cjbarth,

1
Direi che il punto principale è in realtà dove farlo? Quello che hai descritto è piuttosto intuitivo. Ho provato esattamente questo in alcuni strumenti (0xDBE, Visual Studio SQL Server Object Explorer) prima, ma non ho trovato tale funzionalità lì.
David Ferenczy Rogožan,

3
Non possibile! Attività -> Nessuna voce di menu per copiare il database
raiserle

95

È possibile provare a staccare il database, copiare i file con nuovi nomi al prompt dei comandi, quindi collegare entrambi i DB.

In SQL:

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

Al prompt dei comandi (ho semplificato i percorsi dei file per il bene di questo esempio):

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

Di nuovo 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

1
Perfetto! questa è la soluzione unica che ha funzionato per me! molte grazie!
thiagoh,

9
select * from OriginalDB.sys.sysfilesper trovare la posizione dei file del DB.
JohnLBevan,

Sì, anche questa soluzione mi piace di più, poiché non richiede strumenti speciali. Ma non sono stato in grado di creare un NewDB, dice Permission deniedin .mdfarchivio. Non ne ho bisogno ora, avevo solo bisogno di un backup del DB originale, quindi posso sovrascrivere il DB originale con esso in seguito, sono solo curioso di sapere perché sto ricevendo un tale errore.
David Ferenczy Rogožan,

2
Non è necessario scollegare il database originale se è possibile interrompere il servizio sql, copiare i file mdf e ldf, rinominarli per il nuovo database, avviare nuovamente il servizio sql ed eseguire l'ultimo comando di creazione del database sotto il master: USE master ; GO CREATE DATABASE NewDB ON (FILENAME = 'C: \ NewDB.mdf'), (FILENAME = 'C: \ NewDB.ldf') PER ATTACCO; GO
danpop,

1
+1 per il modo più veloce. Oltre all'eccellente commento di @JohnLBevan, puoi anche usareexec sp_helpdb @dbname='TEMPDB';
jean

30

Si è scoperto che avevo tentato di ripristinare in modo errato da un backup.

Inizialmente ho creato un nuovo database e quindi ho tentato di ripristinare il backup qui. Quello che avrei dovuto fare e che alla fine ha funzionato è stato aprire la finestra di dialogo di ripristino e digitare il nome del nuovo database nel campo di destinazione.

Quindi, in breve, il ripristino da un backup ha funzionato.

Grazie per tutti i feedback e suggerimenti ragazzi


Quando lo faccio, la finestra di dialogo mi dice che i file si trovano nella stessa posizione del database da cui ho effettuato il backup. Quindi non ho il coraggio di ripristinare, temendo che i file vengano sovrascritti.
Niels Brinch,

2
Neils, i file sono gli stessi, per impostazione predefinita, nell'istantanea scattata. È possibile modificarne i nomi per creare nuovi file per il database appena nominato.
Colin Dabritz,

PS: questo metodo richiede il servizio SQL Agent, assicurarsi che sia in esecuzione prima di avviare l'operazione di copia db.
dvdmn,

Ora mi hai aiutato tre volte con questa risposta. Continuo a dimenticare di digitarlo invece di crearlo. + birra
Piotr Kula,

Questo e rinominare i file .mdf e .log nella finestra 'Files' ha funzionato per me.
Wollan,

17

Questo è lo script che uso. Un po 'complicato ma funziona. Testato su 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

2
Nel mio ambiente, i nomi dei file non corrispondevano al nome db (proveniente da un altro ripristino), quindi avevo bisogno di 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)una variabile separata per @sourceDb_data con una query simile (sostituendo in files.type=0). HTH!
Dan Caseley,

11

Nessuna delle soluzioni menzionate qui ha funzionato per me: sto usando SQL Server Management Studio 2014.

Invece ho dovuto deselezionare la casella di controllo "Esegui backup del registro di coda prima del ripristino" nella schermata "Opzioni": nella mia versione è selezionata per impostazione predefinita e impedisce il completamento dell'operazione di ripristino. Dopo averlo deselezionato, l'operazione di ripristino è proseguita senza problemi.

inserisci qui la descrizione dell'immagine


2
Questa risposta mi ha salvato la giornata.
Dilhan Jayathilake,

2
Mi ha anche salvato la giornata :)
ashilon,

1
Quando non lo si fa con SQL Server 2017, il database originale è rimasto in "Ripristino in corso ...". La tua soluzione ha funzionato, grazie!
mu88,

9

Utilizzando MS SQL Server 2012, è necessario eseguire 3 passaggi di base:

  1. Innanzitutto, genera un .sqlfile contenente solo la struttura del DB di origine

    • fare clic con il tasto destro sul DB di origine, quindi su Attività, quindi su Genera script
    • seguire la procedura guidata e salvare il .sqlfile localmente
  2. In secondo luogo, sostituire il DB di origine con quello di destinazione nel .sqlfile

    • Fare clic con il tasto destro sul file di destinazione, selezionare Nuova query e Ctrl-Ho ( Modifica - Trova e sostituisci - Sostituzione rapida )
  3. Infine, popolare con i dati

    • Fare clic con il tasto destro sul DB di destinazione, quindi selezionare Attività e Importa dati
    • Il menu a discesa dell'origine dati è impostato su " Provider di dati framework .net per server SQL " + imposta il campo di testo della stringa di connessione in DATA es:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • fare lo stesso con la destinazione
    • selezionare la tabella che si desidera trasferire o selezionare la casella oltre a "origine: ..." per selezionarli tutti

Hai fatto.


A proposito, immagino che i dati di importazione possano creare tabelle se non presenti nelle tabelle di destinazione .. soluzione semplice +1
Khurram Ishaque

6

In SQL Server 2008 R2, eseguire il backup del database come file in una cartella. Quindi scegliere l'opzione di ripristino che appare nella cartella "Database". Nella procedura guidata immettere il nuovo nome desiderato nel database di destinazione. E scegli ripristina da file e usa il file che hai appena creato. L'ho fatto ed è stato molto veloce (il mio DB era piccolo, ma comunque) Pablo.


4

Se il database non è molto grande, è possibile esaminare i comandi "Database script" in SQL Server Management Studio Express, che si trovano in un menu di scelta rapida al di fuori dell'elemento del database stesso in Explorer.

Puoi scegliere cosa scrivere tutto; vuoi gli oggetti e i dati, ovviamente. Quindi salverai l'intero script in un singolo file. Quindi è possibile utilizzare quel file per ricreare il database; assicurati solo che il USEcomando in alto sia impostato sul database corretto.


1
Grazie, tuttavia, il database è piuttosto grande (attorno a un concerto), quindi penso che possano succedere cose brutte :-)
Sergio,

2
Destra; non è il modo migliore allora. Invece, è possibile utilizzare il database degli script per creare la struttura nel nuovo database e quindi importare / esportare per spostare i dati. Assicurati solo di fare prima il Database degli script; L'importazione / esportazione creerà le tabelle se non esistono e potrebbe non piacerti come lo fa.
Andrew Barber,

4

La soluzione, basata su questo commento: https://stackoverflow.com/a/22409447/2399045 . Basta impostare le impostazioni: nome DB, cartella temp, cartella file db. E dopo l'esecuzione avrai la copia di DB con Nome nel formato "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

3

Script basato sulla risposta di Joe ( staccare, copiare i file, allegare entrambi ).

  1. Esegui Managment Studio come account amministratore.

Non è necessario, ma forse è stato negato l'accesso durante l'esecuzione.

  1. Configurare il server sql per eseguire xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Esegui lo script, ma digita prima i tuoi nomi db @dbNamee le @copyDBNamevariabili.
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

3

Potresti semplicemente creare un nuovo database e quindi andare alle attività, importare i dati e importare tutti i dati dal database che vuoi duplicare nel database che hai appena creato.


2

Un altro modo che fa il trucco usando l' importazione / esportazione guidata , crea prima un database vuoto, quindi scegli l'origine che è il tuo server con il database di origine, quindi nella destinazione scegli lo stesso server con il database di destinazione (usando il database vuoto hai creato all'inizio), quindi premi Finish

Creerà tutte le tabelle e trasferirà tutti i dati nel nuovo database,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.