Como clonar um banco de dados do SQL Server no mesmo servidor no SQL Server 2008 Express?

272

Eu tenho um sistema MS SQL Server 2008 Express que contém um banco de dados que eu gostaria de 'copiar e renomear' (para fins de teste), mas não conheço uma maneira simples de conseguir isso.

Percebo que na versão R2 do SQL Server existe um assistente de cópia de banco de dados, mas, infelizmente, não posso atualizar.

O banco de dados em questão está em torno de um show. Tentei restaurar um backup do banco de dados que desejo copiar para um novo banco de dados, mas sem sorte.

Sergio
fonte
2
Restaurar um backup deve funcionar. Você pode fornecer mais detalhes sobre como isso falhou?
Ed Harper
7
Percebi que cometi um erro ao restaurar do backup. Criei um novo banco de dados vazio primeiro e tentei restaurar o backup a partir daí. O que eu deveria ter feito é abrir a caixa de diálogo de restauração e digite o nome do novo banco de dados em vez de criá-lo primeiro. Fazer isso clonou bem o banco de dados!
Sergio

Respostas:

372
  1. Instale o Microsoft SQL Management Studio, que você pode baixar gratuitamente no site da Microsoft:

    Versão 2008

    O Microsoft SQL Management Studio 2008 faz parte do SQL Server 2008 Express com Advanced Services

    Versão 2012

    Clique no botão de download e verifiqueENU\x64\SQLManagementStudio_x64_ENU.exe

    Versão 2014

    Clique no botão de download e verifique MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. Abra o Microsoft SQL Management Studio .

  3. Faça backup do banco de dados original para o arquivo .BAK (db -> Tarefa -> Backup).
  4. Crie um banco de dados vazio com o novo nome (clone). Observe os comentários abaixo, pois isso é opcional.
  5. Clique para clonar o banco de dados e abrir a caixa de diálogo de restauração (veja a imagem) restaurar caixa de diálogo
  6. Selecione Dispositivo e adicione o arquivo de backup na etapa 3. adicionar arquivo de backup
  7. Alterar destino para banco de dados de teste mude o destino
  8. Alterar o local dos arquivos do banco de dados, ele deve ser diferente do original. Você pode digitar diretamente na caixa de texto, basta adicionar o postfix. (NOTA: A ordem é importante. Marque a caixa de seleção e altere os nomes dos arquivos.) mudar localização
  9. Verifique WITH REPLACE e WITH KEEP_REPLICATION com substituir
Tomas Kubes
fonte
84
1. Não crie um banco de dados vazio e restaure o arquivo .bak nele. 2. Use a opção 'Restaurar banco de dados' acessível clicando com o botão direito do mouse na ramificação "Bancos de dados" do SQL Server Management Studio e forneça o nome do banco de dados enquanto fornece a origem para restauração. ref: stackoverflow.com/questions/10204480/…
taynguyen
1
Microsoft SQL Management Studio - é grátis
Tomas Kubes 6/15
4
Não funciona - "Não foi possível obter acesso exclusivo porque o banco de dados está em uso".
Emanuele Ciriachi
5
Eu também tive que desmarcar "Fazer backup do registro de cauda antes de restaurar". Isso foi verificado por padrão e resultou no erro "Acesso exclusivo não pôde ser obtido porque o banco de dados está em uso".
Nabo
3
Meu banco de dados original ficou travado em "Restoring"
Divi perdomo
114

Clique com o botão direito do mouse no banco de dados para clonar, clique Tasks, clique em Copy Database.... Siga o assistente e pronto.

DForck42
fonte
Eu acho que isso está disponível apenas na versão R2 do SQL Server, infelizmente :-(
Sergio
7
aqui está como ele funciona em express: stackoverflow.com/questions/4269450/…
0000
2
Isso não funciona se você tiver objetos criptografados no seu banco de dados.
cjbarth
1
Eu diria que o ponto principal é realmente onde fazê-lo? O que você descreveu é bastante intuitivo. Eu tentei exatamente isso em algumas ferramentas (0xDBE, Visual Studio SQL Server Object Explorer) antes, mas não encontrei esse recurso lá.
David Ferenczy Rogožan
3
Não é possivel! Tarefas -> item de menu Sem a base de dados de cópia
raiserle
95

Você pode tentar desanexar o banco de dados, copiar os arquivos para novos nomes em um prompt de comando e anexar os dois bancos de dados.

No SQL:

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

No prompt de comando (simplifiquei os caminhos do arquivo por causa deste exemplo):

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

No SQL novamente:

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
fonte
1
perfeito! esta é a solução única que funcionou para mim! Muito obrigado!
Thiagoh
9
select * from OriginalDB.sys.sysfilespara encontrar a localização dos arquivos do banco de dados.
21414 John LBevan
Sim, eu também gosto mais desta solução, pois não requer nenhuma ferramenta especial. Mas eu não era capaz de criar um NewDB, diz Permission deniedem .mdfarquivo. Não preciso dele agora, só precisava de um backup do banco de dados original, para poder substituí-lo mais tarde, apenas estou curioso para saber por que estou recebendo esse erro.
David Ferenczy Rogožan
2
Você não precisa desanexar o banco de dados original se puder parar o serviço sql, copiar os arquivos mdf e ldf, renomeá-los para seu novo banco de dados, iniciar o serviço sql novamente e apenas executar o último comando create database no master: USE master ; GO CREATE DATABASE NewDB ON (FILENAME = 'C: \ NewDB.mdf'), (FILENAME = 'C: \ NewDB.ldf') FOR ATTACH; GO
danpop
1
+1 para a maneira mais rápida. Além @JohnLBevan excelente comentário, você também pode usarexec sp_helpdb @dbname='TEMPDB';
jean
30

Acontece que eu tentei restaurar de um backup incorretamente.

Inicialmente, criei um novo banco de dados e tentei restaurar o backup aqui. O que eu deveria ter feito e o que funcionou no final foi abrir a caixa de diálogo de restauração e digitar o nome do novo banco de dados no campo de destino.

Então, resumindo, a restauração de um backup fez o truque.

Obrigado por todos os comentários e sugestões pessoal

Sergio
fonte
Quando faço isso, a caixa de diálogo informa que os arquivos estão no mesmo local que o banco de dados do qual originalmente fiz backup. Portanto, não tenho coragem de restaurar, temendo que os arquivos sejam substituídos.
perfil completo de Niels Brinch
2
Neils, os arquivos são os mesmos, por padrão, na captura instantânea que você tirou. Você pode alterar os nomes deles para criar novos arquivos para o novo banco de dados nomeado.
Colin Dabritz
PS: Este método requer o serviço SQL Agent, verifique se está em execução antes de iniciar a operação de cópia de banco de dados.
dvdmn
Você já me ajudou três vezes com esta resposta. Eu continuo esquecendo de digitá-lo em vez de criá-lo. + cerveja
Piotr Kula
Isso e renomear os arquivos .mdf e .log na janela 'Arquivos' funcionou para mim.
Wollan
17

Este é o script que eu uso. Um pouco complicado, mas funciona. Testado no 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
fonte
2
No meu ambiente, os nomes dos arquivos não correspondiam ao nome do banco de dados (vindo de outra restauração), então eu precisava de 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)uma variável separada para @sourceDb_data com uma consulta semelhante (substituindo em files.type=0). HTH!
Dan Caseley 14/09/16
11

Nenhuma das soluções mencionadas aqui funcionou para mim - estou usando o SQL Server Management Studio 2014.

Em vez disso, tive que desmarcar a caixa de seleção "Fazer backup do log de cauda antes da restauração" na tela "Opções": na minha versão, ela está marcada por padrão e impede que a operação de restauração seja concluída. Após desmarcá-lo, a operação de Restauração prosseguiu sem problemas.

insira a descrição da imagem aqui

Emanuele Ciriachi
fonte
2
Esta resposta salvou meu dia.
Dilhan Jayathilake 5/17/17
2
Salvei meu dia também :)
ashilon
1
Ao não fazer isso com o SQL Server 2017, o banco de dados original permaneceu em "Restaurando ...". Sua solução fez o truque - obrigado!
mu88
9

Usando o MS SQL Server 2012, você precisa executar 3 etapas básicas:

  1. Primeiro, gere um .sqlarquivo contendo apenas a estrutura do banco de dados de origem

    • clique direito sobre a fonte de banco de dados e, em seguida, Tarefas , em seguida, gerar scripts
    • siga o assistente e salve o .sqlarquivo localmente
  2. Segundo, substitua o banco de dados de origem pelo de destino no .sqlarquivo

    • Clique com o botão direito do mouse no arquivo de destino, selecione Nova consulta e Ctrl-Hou ( Editar - Localizar e substituir - Substituição rápida )
  3. Por fim, preencha com dados

    • Clique com o botão direito do mouse no banco de dados de destino e selecione Tarefas e Importar Dados
    • O menu suspenso Origem de dados está definido como " Provedor de dados da estrutura .net para SQL Server " + defina o campo de texto da cadeia de conexão em DATA ex:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • faça o mesmo com o destino
    • marque a tabela que você deseja transferir ou marque a caixa além de "source: ..." para verificar todas elas

Você terminou.

Mehdi Benkirane
fonte
By the way, eu acho importação de dados pode criar tabelas se não estiver presente em tabelas de destino .. solução simples +1
Khurram Ishaque
6

No SQL Server 2008 R2, faça backup do banco de dados como um arquivo em uma pasta. Em seguida, escolha a opção de restauração que aparece na pasta "Banco de Dados". No assistente, digite o novo nome que você deseja no banco de dados de destino. E escolha restaurar do arquivo e use o arquivo que você acabou de criar. Eu apenas fiz e foi muito rápido (meu banco de dados era pequeno, mas ainda assim) Pablo.

pabloelustondo
fonte
4

Se o banco de dados não for muito grande, você poderá observar os comandos 'Script Database' no SQL Server Management Studio Express, que estão em um menu de contexto do item do banco de dados no explorer.

Você pode escolher o que todos devem escrever; você quer os objetos e os dados, é claro. Você salvará o script inteiro em um único arquivo. Em seguida, você pode usar esse arquivo para recriar o banco de dados; apenas verifique se o USEcomando na parte superior está definido no banco de dados apropriado.

Andrew Barber
fonte
1
Graças, o banco de dados é bastante grande no entanto, (em torno de um show) então eu acho que coisas ruins podem acontecer :-)
Sergio
2
Certo; essa não é a melhor maneira então. Em vez disso, você pode usar o banco de dados de scripts para criar apenas a estrutura no novo banco de dados e, em seguida, importar / exportar para mover os dados. Apenas certifique-se de fazer o Script Database primeiro; Importar / Exportar criará as tabelas se elas não existirem, e você pode não gostar de como as faz.
Andrew Barber
4

A solução, com base neste comentário: https://stackoverflow.com/a/22409447/2399045 . Basta definir as configurações: nome do banco de dados, pasta temporária, pasta de arquivos db. E após a execução, você terá a cópia do banco de dados com o nome no 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
fonte
3

Script baseado na resposta de Joe ( desanexar, copiar arquivos, anexar ambos ).

  1. Execute o Managment Studio como conta de administrador.

Não é necessário, mas talvez o erro de acesso negado na execução.

  1. Configurar servidor sql para executar xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. Execute o script, mas digite seus nomes de banco de dados @dbNamee @copyDBNamevariáveis ​​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
fonte
3

Você pode apenas criar um novo banco de dados e, em seguida, ir para tarefas, importar dados e importar todos os dados do banco de dados que você deseja duplicar para o banco de dados que você acabou de criar.

Techie Philosopher
fonte
2

Outra maneira que faz o truque usando o assistente de importação / exportação , primeiro crie um banco de dados vazio, depois escolha a fonte que é seu servidor com o banco de dados de origem e, em seguida, no destino, escolha o mesmo servidor com o banco de dados de destino (usando o banco de dados vazio que você criou primeiro) e pressione Concluir

Ele criará todas as tabelas e transferirá todos os dados para o novo banco de dados,

Mohanad Kaleia
fonte