¿Cómo puedo clonar una base de datos de SQL Server en el mismo servidor en SQL Server 2008 Express?

272

Tengo un sistema MS SQL Server 2008 Express que contiene una base de datos que me gustaría 'copiar y renombrar' (con fines de prueba) pero no conozco una forma simple de lograrlo.

Noté que en la versión R2 de SQL Server hay un asistente de copia de base de datos, pero lamentablemente no puedo actualizar.

La base de datos en cuestión es alrededor de un concierto. Intenté restaurar una copia de seguridad de la base de datos que quiero copiar en una nueva base de datos, pero sin suerte.

Sergio
fuente
2
Restaurar una copia de seguridad debería funcionar. ¿Puedes dar más detalles sobre cómo falló eso?
Ed Harper
77
Me di cuenta de que cometí un error al restaurar desde la copia de seguridad. Primero creé una nueva base de datos vacía e intenté restaurar la copia de seguridad desde allí. Lo que debería haber hecho es abrir el cuadro de diálogo de restauración y escribir el nombre de la nueva base de datos allí en lugar de crearla primero. ¡Hacer esto clonó bien la base de datos!
Sergio

Respuestas:

372
  1. Instale Microsoft SQL Management Studio, que puede descargar de forma gratuita desde el sitio web de Microsoft:

    Versión 2008

    Microsoft SQL Management Studio 2008 es parte de SQL Server 2008 Express con servicios avanzados

    Versión 2012

    Haga clic en el botón de descarga y verifiqueENU\x64\SQLManagementStudio_x64_ENU.exe

    Versión 2014

    Haga clic en el botón de descarga y verifique MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. Abra Microsoft SQL Management Studio .

  3. Copia de seguridad de la base de datos original en un archivo .BAK (db -> Tarea -> Copia de seguridad).
  4. Cree una base de datos vacía con un nuevo nombre (clon). Tenga en cuenta los comentarios a continuación, ya que esto es opcional.
  5. Haga clic para clonar la base de datos y abra el cuadro de diálogo de restauración (ver imagen) restaurar el diálogo
  6. Seleccione Dispositivo y agregue el archivo de respaldo del paso 3. agregar archivo de respaldo
  7. Cambiar destino a base de datos de prueba cambiar destino
  8. Cambiar la ubicación de los archivos de la base de datos, debe ser diferente del original. Puede escribir directamente en el cuadro de texto, simplemente agregue postfix. (NOTA: El orden es importante. Seleccione la casilla de verificación, luego cambie los nombres de los archivos). cambiar locación
  9. Marque CON REEMPLAZAR y CON MANTENER REPLICACIÓN con reemplazar
Tomás Kubes
fuente
84
1. No cree una base de datos vacía y restaure el archivo .bak. 2. Use la opción 'Restaurar base de datos' accesible haciendo clic derecho en la rama "Bases de datos" de SQL Server Management Studio y proporcione el nombre de la base de datos mientras proporciona la fuente para restaurar. ref: stackoverflow.com/questions/10204480/…
taynguyen
1
Microsoft SQL Management Studio - es gratis
Tomas Kubes
44
No funciona: "No se pudo obtener acceso exclusivo porque la base de datos está en uso".
Emanuele Ciriachi
55
También tuve que desmarcar "Realizar copia de seguridad del registro de cola antes de restaurar". Esto se verificó de forma predeterminada y resultó en el error "No se pudo obtener acceso exclusivo porque la base de datos está en uso".
Nabo
3
Mi base de datos original se atascó en "Restauración"
Divi perdomo
114

Haga clic derecho en la base de datos para clonar, haga clic Tasks, haga clic Copy Database.... Sigue al mago y listo.

DForck42
fuente
Creo que lamentablemente solo está disponible en la versión R2 de SQL Server :-(
Sergio
77
así es como funciona en express: stackoverflow.com/questions/4269450/…
Th 00 mÄ s
2
Esto no funciona si tiene objetos cifrados en su base de datos.
cjbarth
1
Yo diría que el punto principal es ¿dónde hacerlo? Lo que describiste es bastante intuitivo. He intentado exactamente eso en algunas herramientas (0xDBE, Visual Studio SQL Server Object Explorer) antes, pero no encontré esa característica allí.
David Ferenczy Rogožan
3
¡Imposible! Tareas -> No hay elemento de menú para copiar la base de datos
Raiserle
95

Puede intentar separar la base de datos, copiar los archivos a nuevos nombres en el símbolo del sistema y luego adjuntar ambos DB.

En SQL:

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

En el símbolo del sistema (he simplificado las rutas de archivo en aras de este ejemplo):

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

En SQL nuevamente:

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
fuente
1
¡Perfecto! ¡Esta es la solución única que funcionó para mí! ¡muchas gracias!
thiagoh
9
select * from OriginalDB.sys.sysfilespara encontrar la ubicación de los archivos de la base de datos.
JohnLBevan
Sí, también me gusta más esta solución, ya que no requiere herramientas especiales. Pero no pude crear un NewDB, dice Permission denieden el .mdfarchivo. No lo necesito ahora, solo necesitaba una copia de seguridad de la base de datos original, para poder sobrescribir la base de datos original con ella más tarde, solo tengo curiosidad de por qué recibo ese error.
David Ferenczy Rogožan
2
No tiene que separar la base de datos original si puede detener el servicio sql, copiar el archivo mdf y ldf, renombrarlos para su nueva base de datos, iniciar el servicio sql nuevamente y simplemente ejecutar el último comando crear base de datos en master: USE master ; IR A CREAR BASE DE DATOS NewDB ON (FILENAME = 'C: \ NewDB.mdf'), (FILENAME = 'C: \ NewDB.ldf') PARA ADJUNTAR; GO
danpop
1
+1 para la forma más rápida. Además del excelente comentario de @JohnLBevan, también puede usarexec sp_helpdb @dbname='TEMPDB';
jean
30

Resulta que había intentado restaurar desde una copia de seguridad incorrectamente.

Inicialmente creé una nueva base de datos y luego intenté restaurar la copia de seguridad aquí. Lo que debería haber hecho, y lo que funcionó al final, fue abrir el diálogo de restauración y escribir el nombre de la nueva base de datos en el campo de destino.

Entonces, en resumen, restaurar desde una copia de seguridad hizo el truco.

Gracias por todos los comentarios y sugerencias chicos

Sergio
fuente
Cuando hago esto, el cuadro de diálogo me dice que los archivos están en la misma ubicación que la base de datos de la que originalmente hice una copia de seguridad. Así que no tengo las agallas para restaurar, por temor a que los archivos se sobrescriban.
Niels Brinch
2
Neils, los archivos son los mismos, por defecto, en la instantánea que tomaste. Puede cambiar los nombres de ellos para crear nuevos archivos para la base de datos recién nombrada.
Colin Dabritz
PD: este método requiere el servicio del Agente SQL, asegúrese de que se esté ejecutando antes de comenzar la operación de copia de db.
dvdmn
Ahora me has ayudado tres veces con esta respuesta. Me olvido de escribirlo en lugar de crearlo. + cerveza
Piotr Kula
Esto y cambiar el nombre de los archivos .mdf y .log en la ventana 'Archivos' me funcionó.
Wollan
17

Este es el guión que uso. Un poco complicado pero funciona. Probado en 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
azulado
fuente
2
En mi entorno, los nombres de los archivos no coincidían con el nombre de la base de datos (que provenía de otra restauración), por lo que necesitaba 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 variable separada para @sourceDb_data con una consulta similar (sustituyendo files.type=0). HTH!
Dan Caseley
11

Ninguna de las soluciones mencionadas aquí funcionó para mí: estoy usando SQL Server Management Studio 2014.

En su lugar, tuve que desmarcar la casilla de verificación "Hacer una copia de seguridad del registro de cola antes de restaurar" en la pantalla "Opciones": en mi versión está marcada por defecto y evita que se complete la operación de restauración. Después de desmarcarlo, la operación de restauración continuó sin problemas.

ingrese la descripción de la imagen aquí

Emanuele Ciriachi
fuente
2
Esta respuesta me salvó el día.
Dilhan Jayathilake
2
También me salvó el día :)
ashilon
1
Al no hacer esto con SQL Server 2017, la base de datos original permaneció en "Restaurando ...". Su solución funcionó: ¡gracias!
mu88
9

Con MS SQL Server 2012, debe realizar 3 pasos básicos:

  1. Primero, genere un .sqlarchivo que contenga solo la estructura de la base de datos fuente

    • haga clic derecho en la base de datos de origen y luego en Tareas y luego en Generar secuencias de comandos
    • siga al asistente y guarde el .sqlarchivo localmente
  2. Segundo, reemplace el DB de origen con el de destino en el .sqlarchivo

    • Haga clic derecho en el archivo de destino, seleccione Nueva consulta y Ctrl-Ho ( Editar - Buscar y reemplazar - Reemplazo rápido )
  3. Finalmente, complete con datos

    • Haga clic derecho en la base de datos de destino, luego seleccione Tareas e Importar datos
    • El menú desplegable de origen de datos se establece en " proveedor de datos de .NET Framework para el servidor SQL " + establece el campo de texto de la cadena de conexión en DATOS, por ejemplo:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • haz lo mismo con el destino
    • marque la tabla que desea transferir o marque la casilla además de "fuente: ..." para marcarlos todos

Estás listo.

Mehdi Benkirane
fuente
Por cierto, supongo que Import Data puede crear tablas si no están presentes en las tablas de destino ... solución simple +1
Khurram Ishaque
6

En SQL Server 2008 R2, haga una copia de seguridad de la base de datos como un archivo en una carpeta. Luego, elija la opción de restauración que aparece en la carpeta "Base de datos". En el asistente, ingrese el nuevo nombre que desea en la base de datos de destino. Y elija restaurar desde el archivo y use el archivo que acaba de crear. Lo hice y fue muy rápido (mi DB era pequeña, pero aún así) Pablo.

pabloelustondo
fuente
4

Si la base de datos no es muy grande, puede mirar los comandos 'Script Database' en SQL Server Management Studio Express, que se encuentran en un menú contextual fuera del elemento de la base de datos en el explorador.

Puedes elegir qué escribir. quieres los objetos y los datos, por supuesto. Luego guardará la secuencia de comandos completa en un solo archivo. Luego puede usar ese archivo para volver a crear la base de datos; solo asegúrese de que el USEcomando en la parte superior esté configurado en la base de datos adecuada.

Andrew Barber
fuente
1
Gracias, sin embargo, la base de datos es bastante grande (alrededor de un concierto), así que creo que pueden pasar cosas malas :-)
Sergio
2
Correcto; esa no es la mejor manera entonces. En su lugar, puede usar la Base de datos de secuencias de comandos para crear la estructura en la nueva base de datos y luego Importar / Exportar para mover los datos. Solo asegúrese de hacer primero la Base de datos de script; Importar / Exportar creará las tablas si no existen, y es posible que no le guste cómo lo hace.
Andrew Barber
4

La solución, basada en este comentario: https://stackoverflow.com/a/22409447/2399045 . Simplemente configure: nombre de la base de datos, carpeta temporal, carpeta de archivos db. Y después de ejecutar, tendrá la copia de DB con Nombre en 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
Pavel Samoylenko
fuente
3

Script basado en la respuesta de Joe ( separar, copiar archivos, adjuntar ambos ).

  1. Ejecute Managment Studio como cuenta de administrador.

No es necesario, pero tal vez acceso denegado error al ejecutar.

  1. Configurar el servidor sql para ejecutar xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Ejecute script, pero escriba sus nombres de db @dbNamey @copyDBNamevariables antes.
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
fuente
3

Puede crear una nueva base de datos y luego ir a tareas, importar datos e importar todos los datos de la base de datos que desea duplicar a la base de datos que acaba de crear.

Filósofo técnico
fuente
2

Otra forma de hacer el truco usando el asistente de importación / exportación , primero crea una base de datos vacía, luego elige la fuente que es tu servidor con la base de datos de origen, y luego en el destino elige el mismo servidor con la base de datos de destino (usando la base de datos vacía creaste al principio), luego presiona finalizar

Creará todas las tablas y transferirá todos los datos a la nueva base de datos,

Mohanad Kaleia
fuente