none
Copiar ou fazer Backup de Banco para o mesmo local com outro nome via T-SQL RRS feed

  • Pergunta

  • Caros colegas,

    Fiz um esquema de Backup via T-SQL executado em uma "Stored Procedure" para fazer um Backup do Banco de dados do SQL Server 2008 R2 para o disco informando como parâmetros o caminho onde salvar adiciono outros valores de data e hora para complementar o nome do arquivo e está funcionando perfeitamente. Preciso agora criar outra "Stored Procedure" para COPIAR o banco de dados atual para o mesmo local com outro nome. Exemplo: Nome do Banco atual "StudioWorks", quero que a rotina faça uma cópia exata(full) desse banco no mesmo local para o nome "StudioWorks_Teste". Para que isso, quando os usuários tem dúvidas no sistema quando vão fazer alguma operação ou quando estão somente fazendo testes para aprender eu crio uma base de testes para que fiquem alimentando sem se preocupar em poluir a base oficial.

    Tentei da seguinte maneira mas não funcionou.

    SELECT DB_NAME() AS [Current Database];
    GO

    /****** Object:  StoredProcedure [dbo].[CRIA_TESTE]    Script Date: 09/20/2012 10:57:07 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE PROCEDURE [dbo].[CRIA_TESTE]

    AS

    BEGIN

    /* DECLARA VARIAVEIS  */

    DECLARE @BD VARCHAR(60)
    DECLARE @BANCOTESTE VARCHAR(30)

    /* ATRIBUI O VALOR _Teste NA VARIAVEL  */

    SET @BD = DB_NAME()
    SET @BANCOTESTE =  (@BD)+ '_Teste'

    /* INSTRUÇÃO DE BACKUP */
    --BACKUP DATABASE [SOLL]

    BACKUP DATABASE @BD TO @BANCOTESTE

    WITH

      INIT,

      NOUNLOAD,

      NAME = N'@BD',

      NOSKIP ,

      STATS = 10,

      NOFORMAT

    END

    Alguém já fez isso?

    Obrigado.

    quinta-feira, 20 de setembro de 2012 14:36

Respostas

  • Richardinho, 
    Fiz o seguinte, declarei uma nova variável @banco_atual e setei para selecionar o banco atual @banco_atual = (select db_name()) e fiz que o backup database recebesse essa nova variável para que não precisasse 'engessar' o nome do banco de dados.

    if exists (select 1 from sys.procedures where name='backup_automatico')	
    	drop procedure backup_automatico
    go
    
    create procedure backup_automatico
    as
    declare @BD VARCHAR(60)
    declare @BANCOTESTE VARCHAR(30)
    declare @BANCO_ATUAL VARCHAR(30)
    
    set @BD = 'c:\test\'+DB_NAME() 
    set @BANCOTESTE =  'c:\test\'+DB_NAME()+'_teste'
    set @BANCO_ATUAL = (SELECT DB_NAME())
    
    backup database @BANCO_ATUAL
    to disk = @BD
    mirror to disk = @BANCOTESTE
    WITH FORMAT INIT, NOUNLOAD, STATS = 10
    
    --exec backup_automatico

    Se você testar, pode ver que não vai precisa fazer nada, só executar a procedure que você vai ter os 2 Backup's no diretório de sua escolha, tanto o bkp original como o _teste.


    []'s

    sexta-feira, 21 de setembro de 2012 12:20

Todas as Respostas

  • Richardinho, 

    Pelo que eu entendi, não vai ser necessário você criar uma nova Stored procedure para essa ação, pois no seu primeiro Backup você pode usar a opção MIRROR TO DISK = 'Diretório\Nome_do_backup.bak', ficaria mais ou menos assim.

    BACKUP DATABASE Teste TO DISK = 'c:\teste\1_teste_backup_20_09_2012.bak' MIRROR TO DISK = 'c:\teste\2_teste_backup_20_09_2012.bak'

    WITH FORMAT,

      INIT,
      NOUNLOAD,
      STATS = 10 


    Essa opção espelha o seu backup para um diretório alternativo.

    No seu caso, seta sua segunda variável com diretório e concatena com o nome do db e informe na linha do MIRROR TO DISK, segue exemplo abaixo:

    DECLARE @BD VARCHAR(60)
    DECLARE @BANCOTESTE VARCHAR(30)
    /* ATRIBUI O VALOR _Teste NA VARIAVEL  */
    SET @BD = 'c:\test\'+DB_NAME()+'.bak'
    SET @BANCOTESTE =  'c:\test\'+DB_NAME()+'_teste.bak'
    /* INSTRUÇÃO DE BACKUP */
    --BACKUP DATABASE [SOLL]
    BACKUP DATABASE Nome_Banco
    to disk = @BD
    mirror to disk = @BANCOTESTE
    WITH FORMAT,
      INIT,
      NOUNLOAD,
      STATS = 10


    []'s






    quinta-feira, 20 de setembro de 2012 15:31
  • Caro Fernando Maradei,

    Obrigado pela resposta mas na verdade eu quero fazer um pouco diferente. Quero criar nessa Stored Procedure para que ela faça a cópia do Banco com o mesmo nome acrescido de "_Teste" tanto no nome do arquivo físico no disco quanto na Cópia para dentro do SQL Express, no mesmo local onde está o outro. O detalhe é que isso vai ser feito pelo usuário clicando um simples botão. Nesse botão que quero colocar ele não vai pedir nada, então nessa Stored Procedure ele teria que pegar o nome e o diretório atual do banco "Oficial", verificar se já existe uma cópia do Banco com o nome de teste e se sim apagar ou sobrescrever. Isso tudo porque são vários Bancos em vários Servidores diferentes e pastas diferentes, então não posso "engessar" o nome do Banco e a pasta onde está.

    A idéia disso é fazer com que o usuário decida quando quer fazer uma cópia do Banco Oficial para o Teste quando ele quiser. Hoje eu tenho que ficar fazendo a toda hora. Deixando dessa maneira que comentei eu fico "livre".

    Tem alguma idéia de como fazer isso?

    Obrigado antecipado.

    quinta-feira, 20 de setembro de 2012 20:50
  • Richardinho, 
    Fiz o seguinte, declarei uma nova variável @banco_atual e setei para selecionar o banco atual @banco_atual = (select db_name()) e fiz que o backup database recebesse essa nova variável para que não precisasse 'engessar' o nome do banco de dados.

    if exists (select 1 from sys.procedures where name='backup_automatico')	
    	drop procedure backup_automatico
    go
    
    create procedure backup_automatico
    as
    declare @BD VARCHAR(60)
    declare @BANCOTESTE VARCHAR(30)
    declare @BANCO_ATUAL VARCHAR(30)
    
    set @BD = 'c:\test\'+DB_NAME() 
    set @BANCOTESTE =  'c:\test\'+DB_NAME()+'_teste'
    set @BANCO_ATUAL = (SELECT DB_NAME())
    
    backup database @BANCO_ATUAL
    to disk = @BD
    mirror to disk = @BANCOTESTE
    WITH FORMAT INIT, NOUNLOAD, STATS = 10
    
    --exec backup_automatico

    Se você testar, pode ver que não vai precisa fazer nada, só executar a procedure que você vai ter os 2 Backup's no diretório de sua escolha, tanto o bkp original como o _teste.


    []'s

    sexta-feira, 21 de setembro de 2012 12:20
  • Caro Fernando,

    Quase isso. O problema nessa solução que passou resolve em partes pois no caso eu tenho vários servidores e neles a localização fisica(pasta) onde estão os arquivos são diferentes e nesse exemplo teria que personalizar para cada um dos bancos e são vários. Para funcionar eu teria que pegar o diretório corrente onde eles se encontram também e não especificar um.

    A sequencia que deveria ocorrer é a seguinte:

    Tenho lá dentro do SQL Managemente Studio:

    [-] 192.168.1.254 (SQL Server 10.50.2500 -sa)
         [-] Bancos de Dados
             [+] Bancos de dados do Sistema
             [+] Instantâneos do Banco de Dados
             [+] BDOficial -> Esse seria o banco oficial atual que vai ser feita a cópia com o nome teste e colocado online
             [+] ReportServer
             [+] ReportServerTempDB
    [+] Segurança
    [+] Objetos de Servidor
    [+] Replicação
    [+] Gerenciamento
    [+] SQL Server Agent

    O que deveria acontecer após executado o procedimento:

    [-] 192.168.1.254 (SQL Server 10.50.2500 -sa)
         [-] Bancos de Dados
             [+] Bancos de dados do Sistema
             [+] Instantâneos do Banco de Dados
             [+] BDOficial
             [+] BDOficial_Teste
             [+] ReportServer
             [+] ReportServerTempDB
    [+] Segurança
    [+] Objetos de Servidor
    [+] Replicação
    [+] Gerenciamento
    [+] SQL Server Agent

    Ou seja, o procedimento teria que duplicar o Banco atual acrescido do _Teste e colocado online como se tivesse feito um Backup e restaurado com outro nome. Acredito que ao efetuar isso eu tenha que verificar se os arquivos BDOficial_Teste.mdf e BDOficial_Teste.log existem no diretório corrente e apagá-los antes.

    Obrigado.

    sexta-feira, 21 de setembro de 2012 15:31
  • Não entendi essa parte 'localização fisica(pasta) ';


    Os valores que foram atribuídos as variáveis @BD e @BANCOTESTE  são diretórios para onde estão indo seus Backups que futuramente você pode acessar esse diretório e restaurá-los e não o diretórios de seus arquivos físicos (MDF e LDF) de cada banco de dados.

    Só para entendimento de como funcionará na aplicação,

    Esse 'Vários' bancos não estão tudo na mesma instância? Então, se tiver, o usuário na aplicação irá selecionar o banco de dados, e nesse banco de dados terá um botão chamado 'Backup', Deseja fazer backup? Sim ou Não, certo? Se ele colocar que sim, à aplicação chamará a procedure que irá fazer o processo de backup do banco (selecionado pelo usuário no começo), jogando esses dois arquivos de backup no diretório setado nas variáveis @BD e @BANCOTESTE.



    []'s

    sexta-feira, 21 de setembro de 2012 17:12
  • Caro Fernando,

    Para você entender melhor a situação, são vários servidores diferentes em localizações físicas diferentes, pastas diferentes, instâncias diferentes, nomes de bancos diferentes mas todos usam o mesmo banco e a mesma aplicação. Quando faço alguma alteração no Banco eu uso um aplicativo para sincronizar essas bases com o meu servidor local através da internet. Conforme alguns clientes vão pedindo a cópia da base oficial para base de testes para eles ficarem "fuçando" só apra ver o que acontece ou mesmo para treinar eu vou acessando via Terminal Server e através do SQL Management faço o Backup e restauro com o nome atual + _Teste que a aplicação já tem a conexão para essas bases.

    A dificuldade está justamente aí. As pastas físicas são diferentes, em um fica no d:\BD\Backup, no outro local é outra pasta e assim por diante. Por isso a necessidade de se "pegar" o nome do Banco atual + a localização física dele ex: d:\BD\BDOficial.mdf para caso a caso e sendo assim se eu informar uma localização no procedure não servirá para o outro. Tenho que pegar ela mesmo no procedimento através de algum comando.

    Não sei se compreendeu mas eu preciso mesmo é que a rotina coloque o mesmo banco que está rodando como cópia e online. O procedimento do Backup é uma mera consequencia do processo. Não sei se daria para fazer uma cópia direta sem ser por backup pois quando faço pelo Management Studio é possível.

    Na aplicação funcionaria assim: Deseja fazer uma cópia da Base Oficial para a de Testes? Sim ou Não. Se SIM ele pega o nome da base que está usando + a localização física dos arquivos do Banco(MDF e LOG) dele, verifica se o nome da Base_Teste já existe, faz um backup no mesmo local e restaura com o mesmo nome + _Teste.

    Não sei se fui claro e obrigado novamente por sua paciência.

    segunda-feira, 24 de setembro de 2012 15:11
  • Ricardinho,

    Cara não seria melhor pensarmos em algo relacionado a alta disponibilidade?

    • Log Shipping;
    • Database Mirroring;
    • Replication Database; e
    • Cluster.

    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    terça-feira, 25 de setembro de 2012 13:57
    Moderador
  • Junior,

    Acho que não seria o caso pois em alguns lugares onde estão os servidores, a Infra que existe é bem básica mesmo. Essa demanda da cópia é maior onde os usuários estão começando. Depois com a prática, esse processo tende a diminuir.

    Obrigado.



    • Editado Richardinho quinta-feira, 27 de setembro de 2012 18:07
    terça-feira, 25 de setembro de 2012 14:57