Comment puis-je cloner une base de données SQL Server sur le même serveur dans SQL Server 2008 Express?

272

J'ai un système MS SQL Server 2008 Express qui contient une base de données que je voudrais «copier et renommer» (à des fins de test) mais je ne connais pas de moyen simple d'y parvenir.

Je remarque que dans la version R2 de SQL Server, il existe un assistant de copie de base de données, mais malheureusement, je ne peux pas mettre à niveau.

La base de données en question tourne autour d'un concert. J'ai tenté de restaurer une sauvegarde de la base de données que je souhaite copier dans une nouvelle base de données, mais sans succès.

Sergio
la source
2
La restauration d'une sauvegarde devrait fonctionner. Pouvez-vous fournir plus de détails sur la façon dont cela a échoué?
Ed Harper
7
J'ai réalisé que j'avais fait une erreur lors de la restauration à partir d'une sauvegarde. J'ai d'abord créé une nouvelle base de données vide et tenté de restaurer la sauvegarde à partir de là. Ce que j'aurais dû faire, c'est faire apparaître la boîte de dialogue de restauration et taper le nom de la nouvelle base de données là-dedans au lieu de la créer d'abord. Faire cela a bien cloné la base de données!
Sergio

Réponses:

372
  1. Installez Microsoft SQL Management Studio, que vous pouvez télécharger gratuitement sur le site Web de Microsoft:

    Version 2008

    Microsoft SQL Management Studio 2008 fait partie de SQL Server 2008 Express avec Advanced Services

    Version 2012

    Cliquez sur le bouton de téléchargement et vérifiezENU\x64\SQLManagementStudio_x64_ENU.exe

    Version 2014

    Cliquez sur le bouton de téléchargement et vérifiez MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. Ouvrez Microsoft SQL Management Studio .

  3. Sauvegardez la base de données d'origine dans un fichier .BAK (db -> Tâche -> Sauvegarde).
  4. Créez une base de données vide avec un nouveau nom (clone). Notez les commentaires ci-dessous car cela est facultatif.
  5. Cliquez pour cloner la base de données et ouvrir la boîte de dialogue de restauration (voir image) boîte de dialogue de restauration
  6. Sélectionnez Appareil et ajoutez le fichier de sauvegarde à l'étape 3. ajouter un fichier de sauvegarde
  7. Modifier la destination pour tester la base de données changer de destination
  8. Modifiez l'emplacement des fichiers de base de données, il doit être différent de l'original. Vous pouvez taper directement dans la zone de texte, ajoutez simplement le suffixe. (REMARQUE: l'ordre est important. Cochez la case, puis modifiez les noms de fichiers.) changer de lieu
  9. Vérifiez AVEC REMPLACER et AVEC KEEP_REPLICATION avec remplacer
Tomas Kubes
la source
84
1. Ne créez pas une base de données vide et restaurez-y le fichier .bak. 2. Utilisez l'option «Restaurer la base de données» accessible en cliquant avec le bouton droit sur la branche «Bases de données» de SQL Server Management Studio et indiquez le nom de la base de données tout en fournissant la source à restaurer. ref: stackoverflow.com/questions/10204480/…
taynguyen
1
Microsoft SQL Management Studio - c'est gratuit
Tomas Kubes
4
Ne fonctionne pas - "Accès exclusif n'a pas pu être obtenu car la base de données est en cours d'utilisation".
Emanuele Ciriachi
5
J'ai également dû décocher "Prendre la sauvegarde du journal de queue avant la restauration". Cela a été vérifié par défaut et a entraîné l'erreur «Accès exclusif impossible car la base de données est en cours d'utilisation».
Navet
3
Ma base de données d'origine est restée bloquée sur "Restauration"
Divi perdomo
114

Cliquez avec le bouton droit sur la base de données à cloner, cliquez sur Tasks, cliquez sur Copy Database.... Suivez l'assistant et vous avez terminé.

DForck42
la source
Je pense que cela n'est malheureusement disponible que dans la version R2 de SQL Server :-(
Sergio
7
voici comment cela fonctionne en express: stackoverflow.com/questions/4269450/…
00
2
Cela ne fonctionne pas si vous avez des objets chiffrés dans votre base de données.
cjbarth
1
Je dirais que le point principal est en fait où le faire? Ce que vous avez décrit est assez intuitif. J'ai essayé exactement cela dans certains outils (0xDBE, Explorateur d'objets Visual Studio SQL Server) auparavant, mais je n'ai pas trouvé une telle fonctionnalité là-bas.
David Ferenczy Rogožan
3
Pas possible! Tâches -> Aucun élément de menu pour copier la base de données
raiserle
95

Vous pouvez essayer de détacher la base de données, copier les fichiers sous de nouveaux noms à l'invite de commandes, puis attacher les deux bases de données.

En SQL:

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

À l'invite de commande (j'ai simplifié les chemins d'accès aux fichiers pour cet exemple):

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

En SQL à nouveau:

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
la source
1
parfait! c'est la solution unique qui a fonctionné pour moi! Merci beaucoup!
thiagoh
9
select * from OriginalDB.sys.sysfilespour trouver l'emplacement des fichiers de la base de données.
JohnLBevan
Oui, j'aime aussi le plus cette solution, car elle ne nécessite aucun outil spécial. Mais je n'ai pas pu créer de NewDB, dit- Permission deniedon au .mdfdossier. Je n'en ai pas besoin maintenant, j'avais juste besoin d'une sauvegarde de la base de données d'origine, donc je peux écraser la base de données d'origine plus tard, je suis juste curieux de savoir pourquoi j'obtiens une telle erreur.
David Ferenczy Rogožan
2
Vous n'avez pas besoin de détacher la base de données d'origine si vous pouvez arrêter le service sql, copier les fichiers mdf et ldf, les renommer pour votre nouvelle base de données, redémarrer le service sql et simplement exécuter la dernière commande create database sous master: USE master ; GO CREATE DATABASE NewDB ON (FILENAME = 'C: \ NewDB.mdf'), (FILENAME = 'C: \ NewDB.ldf') FOR ATTACH; GO
danpop
1
+1 pour le moyen le plus rapide. En plus de l'excellent commentaire de @JohnLBevan, vous pouvez également utiliserexec sp_helpdb @dbname='TEMPDB';
jean
30

Il s'avère que j'avais tenté de restaurer à partir d'une sauvegarde de manière incorrecte.

Au départ, j'ai créé une nouvelle base de données, puis j'ai tenté de restaurer la sauvegarde ici. Ce que j'aurais dû faire, et ce qui a finalement fonctionné, était d'afficher la boîte de dialogue de restauration et de taper le nom de la nouvelle base de données dans le champ de destination.

Donc, en bref, la restauration à partir d'une sauvegarde a fait l'affaire.

Merci pour tous les commentaires et suggestions les gars

Sergio
la source
Lorsque je fais cela, la boîte de dialogue m'indique que les fichiers se trouvent au même emplacement que la base de données à partir de laquelle j'ai sauvegardé à l'origine. Je n'ai donc pas le courage de restaurer, craignant que les fichiers ne soient écrasés.
Niels Brinch
2
Neils, les fichiers sont les mêmes, par défaut, dans l'instantané que vous avez pris. Vous pouvez en changer le nom pour créer de nouveaux fichiers pour la base de données nouvellement nommée.
Colin Dabritz
PS: Cette méthode nécessite le service SQL Agent, assurez-vous qu'elle est en cours d'exécution avant de démarrer l'opération de copie db.
dvdmn
Vous m'avez maintenant aidé trois fois avec cette réponse. J'oublie toujours de le taper au lieu de le créer. + bière
Piotr Kula
Cela et renommer les fichiers .mdf et .log dans la fenêtre «Fichiers» a fonctionné pour moi.
Wollan
17

Ceci est le script que j'utilise. Un peu délicat mais ça marche. Testé sur 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
bleuâtre
la source
2
Dans mon environnement, les noms de fichiers ne correspondaient pas au nom de la base de données (provenant d' une autre restauration), j'avais donc besoin d' 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)une variable distincte pour @sourceDb_data avec une requête similaire (en la remplaçant files.type=0). HTH!
Dan Caseley
11

Aucune des solutions mentionnées ici n'a fonctionné pour moi - j'utilise SQL Server Management Studio 2014.

Au lieu de cela, j'ai dû décocher la case "Prendre la sauvegarde du journal de queue avant la restauration" dans l'écran "Options": dans ma version, elle est cochée par défaut et empêche l'opération de restauration d'être terminée. Après l'avoir décochée, l'opération de restauration s'est déroulée sans problème.

entrez la description de l'image ici

Emanuele Ciriachi
la source
2
Cette réponse m'a sauvé la journée.
Dilhan Jayathilake
2
J'ai aussi sauvé ma journée :)
ashilon
1
Lorsque vous ne faites pas cela avec SQL Server 2017, la base de données d'origine est restée dans "Restauration ...". Votre solution a fait l'affaire - merci!
mu88
9

À l'aide de MS SQL Server 2012, vous devez effectuer 3 étapes de base:

  1. Tout d'abord, générez un .sqlfichier contenant uniquement la structure de la base de données source

    • clic droit sur la base de données source puis sur Tâches puis Générer des scripts
    • suivez l'assistant et enregistrez le .sqlfichier localement
  2. Ensuite, remplacez la base de données source par celle de destination dans le .sqlfichier

    • Cliquez avec le bouton droit sur le fichier de destination, sélectionnez Nouvelle requête et Ctrl-Hou ( Modifier - Rechercher et remplacer - Remplacement rapide )
  3. Enfin, remplissez de données

    • Cliquez avec le bouton droit sur la base de données de destination, puis sélectionnez Tâches et importation de données
    • Liste déroulante de la source de données définie sur " .net framework data provider for SQL server " + définissez le champ de texte de la chaîne de connexion sous DATA ex:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • faire de même avec la destination
    • cochez la table que vous souhaitez transférer ou cochez la case "source: ..." pour les cocher toutes

Vous avez terminé.

Mehdi Benkirane
la source
Soit dit en passant, je suppose que l'importation de données peut créer des tables si elles ne sont pas présentes dans les tables de destination. Solution simple +1
Khurram Ishaque
6

Dans SQL Server 2008 R2, sauvegardez la base de données sous forme de fichier dans un dossier. Choisissez ensuite l'option de restauration qui apparaît dans le dossier "Base de données". Dans l'assistant, entrez le nouveau nom que vous souhaitez dans la base de données cible. Et choisissez restaurer le fichier frrom et utilisez le fichier que vous venez de créer. Je l'ai fait et c'était très rapide (ma DB était petite, mais quand même) Pablo.

pabloelustondo
la source
4

Si la base de données n'est pas très grande, vous pouvez consulter les commandes «Script Database» dans SQL Server Management Studio Express, qui se trouvent dans un menu contextuel de l'élément de base de données lui-même dans l'explorateur.

Vous pouvez choisir ce que tout le script; vous voulez les objets et les données, bien sûr. Vous enregistrerez ensuite l'intégralité du script dans un seul fichier. Ensuite, vous pouvez utiliser ce fichier pour recréer la base de données; assurez-vous simplement que la USEcommande en haut est définie sur la base de données appropriée.

Andrew Barber
la source
1
Merci, la base de données est cependant assez volumineuse (autour d'un concert), donc je pense que de mauvaises choses peuvent arriver :-)
Sergio
2
Droite; ce n'est pas la meilleure façon alors. Au lieu de cela, vous pouvez utiliser la base de données de script pour simplement créer la structure dans la nouvelle base de données, puis importer / exporter pour déplacer les données. Assurez-vous simplement de commencer par la base de données de scripts; L'importation / exportation créera les tables si elles n'existent pas, et vous n'aimerez peut-être pas la façon dont elles le font.
Andrew Barber
4

La solution, basée sur ce commentaire: https://stackoverflow.com/a/22409447/2399045 . Définissez simplement les paramètres: nom de la base de données, dossier temporaire, dossier des fichiers db. Et après l'exécution, vous aurez la copie de la base de données avec le nom au format "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
la source
3

Script basé sur la réponse de Joe ( détacher, copier des fichiers, joindre les deux ).

  1. Exécutez Managment Studio en tant que compte administrateur.

Ce n'est pas nécessaire, mais peut-être que l'accès a été refusé lors de l'exécution.

  1. Configurer le serveur SQL pour exécuter xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Exécutez le script, mais saisissez vos noms de base de données @dbNameet @copyDBNamevariables avant.
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
la source
3

Vous pouvez simplement créer une nouvelle base de données, puis accéder aux tâches, importer des données et importer toutes les données de la base de données que vous souhaitez dupliquer dans la base de données que vous venez de créer.

Philosophe Techie
la source
2

Une autre façon de faire l'affaire en utilisant l'assistant d'importation / exportation , créez d'abord une base de données vide, puis choisissez la source qui est votre serveur avec la base de données source, puis dans la destination, choisissez le même serveur avec la base de données de destination (en utilisant la base de données vide vous avez créé au début), puis appuyez sur terminer

Il va créer toutes les tables et transférer toutes les données dans la nouvelle base de données,

Mohanad Kaleia
la source