T-SQL Tuesday #26 – Segundas Chances


Todo mundo merece uma segunda chance,, ou para fazer melhor, ou para simplesmente não fazer,,, então,,, até no SQL temos uma segunda chance…

Dessa vez o Sr. David Howard (Blog | Twitter) deu a oportunidade de escrevermos novamente sobre algum tópico anterior do T-SQL Tuesday, ou para melhora-lo ou para fazer um se você não participou…

Eu resolvi melhorar o meu script para montar um Mirror com SQLCMD,,, na versão anterior (#25) se o banco de dados tiver mais que um datafile você tem que modificar o script na mão e compensar a criação desse outro arquivo… Nesta versão o script vai ler o arquivo de backup em uma temp table e montar o script de restore com todas as variáveis…

Vale lembrar que você precisa habilitar a opção de SQLCMD no SSMS e não esqueça de trocar o caminho do backup…

Everyone deserves a second chance, or to do better or to simply not do, then, even in SQL havea second chance…
This time Mr. David Howard (blog | twitter) gave us the opportunity to write again about a previous topic of Tuesday’s T-SQL, or to improve it or make one if you did not participate …
I decided to improve my script to create a Mirror with SQLCMD, in the previous version (#25) if the database has more than one datafile you have to modify the script and make the creation of another file … this version will read backup file in a temp table and mount the restore script with all the variables …
Remember that you need to enable the option of SQLCMD in SSMS and do not forget to change the backup path …

:SETVAR PrincipalServer (local)\INST01
:SETVAR MirrorServer (local)\INST02
:SETVAR SERVER (servername)
:SETVAR db DB_NAME
go

:ON ERROR EXIT
go

:CONNECT $(PrincipalServer)

ALTER DATABASE $(db)
 SET RECOVERY FULL
go

CREATE ENDPOINT Mirroring
 STATE=STARTED
 AS TCP (LISTENER_PORT=5091)
 FOR DATABASE_MIRRORING (ROLE=ALL)
GO

:CONNECT $(MirrorServer)

CREATE ENDPOINT Mirroring
 STATE=STARTED
 AS TCP (LISTENER_PORT=5092)
 FOR DATABASE_MIRRORING (ROLE=ALL)
GO

:CONNECT $(PrincipalServer)

BACKUP DATABASE $(db)
TO DISK = 'D:\DB01\local\$(db).bak'
WITH INIT
GO

:CONNECT $(MirrorServer)

DECLARE @InstanceName sql_variant,
 @InstanceDir sql_variant,
 @SQLDataRoot nvarchar(512),
 @ExecStr nvarchar(max)

SELECT @InstanceName = ISNULL(SERVERPROPERTY('InstanceName'), 'MSSQLServer')

EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
 'SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL',
 @InstanceName, @InstanceDir OUTPUT

SELECT @ExecStr = 'EXECUTE master.dbo.xp_regread '
 + '''HKEY_LOCAL_MACHINE'', '
 + '''SOFTWARE\Microsoft\Microsoft SQL Server\'
 + convert(varchar, @InstanceDir)
 + '\Setup'', ''SQLDataRoot'', @SQLDataRoot OUTPUT'

EXEC master.dbo.sp_executesql @ExecStr
 , N'@SQLDataRoot nvarchar(512) OUTPUT'
 , @SQLDataRoot OUTPUT

IF @SQLDataRoot IS NULL
BEGIN
 RAISERROR ('I can´t find where restore the Database... I going to stop...', 16, -1)
END

CREATE TABLE #BackupFileList
( LogicalName sysname NULL
 , PhysicalName sysname NULL
 , [Type] char(1)
 , FileGroupName sysname NULL
 , Size bigint
 , MaxSize bigint
 , FileId smallint
 , CreateLSN numeric(25,0)
 , DropLSN numeric(25,0)
 , UniqueId uniqueidentifier
 , ReadOnlyLSN numeric(25,0)
 , ReadWriteLSN numeric(25,0)
 , BackupSizeInBytes bigint
 , SourceBlockSize bigint
 , FileGroupId smallint
 , LogGroupGUID uniqueidentifier
 , DifferentialBaseLSN numeric(25,0)
 , DifferentialBaseGUID uniqueidentifier
 , IsReadOnly bit
 , IsPresent bit
 , TDEThumbPrint varbinary(32)
)

INSERT #BackupFileList
 EXEC('RESTORE FILELISTONLY FROM DISK = ''D:\DB01\local\$(db).bak''')

UPDATE #BackupFileList
 SET PhysicalName
 = @SQLDataRoot
 + N'\Data\'
 + REVERSE(SUBSTRING(REVERSE(PhysicalName)
 , 1, PATINDEX('%\%', REVERSE(PhysicalName)) -1))

DECLARE @LogicalName sysname
 , @PhysicalName sysname

DECLARE FileListCursor CURSOR FAST_FORWARD FOR
 SELECT LogicalName, PhysicalName
 FROM #BackupFileList

OPEN FileListCursor

FETCH NEXT FROM FileListCursor INTO @LogicalName, @PhysicalName

SELECT @ExecStr = N'RESTORE DATABASE $(db)' +
 N' FROM DISK = ''D:\DB01\local\$(db).bak''' +
 N' WITH MOVE ''' + @LogicalName + N''' TO ''' + @PhysicalName + N''''

FETCH NEXT FROM FileListCursor INTO @LogicalName, @PhysicalName

WHILE @@FETCH_STATUS <> -1
BEGIN
 SELECT @ExecStr = @ExecStr + N', MOVE ''' + @LogicalName
 + ''' TO ''' + @PhysicalName + ''''
 FETCH NEXT FROM FileListCursor INTO @LogicalName, @PhysicalName
END

SELECT @ExecStr = @ExecStr + N' , NORECOVERY, REPLACE'

-- if you receive the error message because the script don´t found where he need to restore, you can uncomment the next line and get the restore command,,,
-- to restore manual...
-- SELECT @ExecStr

EXEC (@ExecStr)

DEALLOCATE FileListCursor
GO

:CONNECT $(PrincipalServer)
SELECT DATABASEPROPERTYEX(N'$(db)', N'Status') AS 'Principal Database State' -- Returns ONLINE
SELECT db_name(sd.[database_id]) AS [Database Name],
 sd.mirroring_guid,
 sd.mirroring_state,
 sd.mirroring_state_desc,
 sd.mirroring_partner_name,
 sd.mirroring_witness_name,
 sd.mirroring_witness_state,
 sd.mirroring_witness_state_desc,
 sd.mirroring_role,
 sd.mirroring_role_desc,
 sd.mirroring_role_sequence,
 sd.mirroring_safety_level,
 sd.mirroring_safety_level_desc,
 sd.mirroring_safety_sequence,
 sd.mirroring_failover_lsn
FROM sys.database_mirroring AS sd
WHERE sd.[database_id] = db_id(N'$(db)')
go

:CONNECT $(MirrorServer)
SELECT DATABASEPROPERTYEX(N'$(db)', N'Status') AS 'Mirror Database State' -- Returns RESTORING
SELECT db_name(sd.[database_id]) AS [Database Name],
 sd.mirroring_guid,
 sd.mirroring_state,
 sd.mirroring_state_desc,
 sd.mirroring_partner_name,
 sd.mirroring_witness_name,
 sd.mirroring_witness_state,
 sd.mirroring_witness_state_desc,
 sd.mirroring_role,
 sd.mirroring_role_desc,
 sd.mirroring_role_sequence,
 sd.mirroring_safety_level,
 sd.mirroring_safety_level_desc,
 sd.mirroring_safety_sequence,
 sd.mirroring_failover_lsn
FROM sys.database_mirroring AS sd
WHERE sd.[database_id] = db_id(N'$(db)')
go

:CONNECT $(PrincipalServer)

BACKUP LOG $(db)
TO DISK = 'D:\DB01\local\$(db)_Log.bak'
WITH INIT
GO

:CONNECT $(MirrorServer)

RESTORE LOG $(db)
FROM DISK = 'D:\DB01\local\$(db)_Log.bak'
WITH NORECOVERY
GO

ALTER DATABASE $(db)
 SET PARTNER = 'TCP://$(server):5091'
GO

:CONNECT $(PrincipalServer)

ALTER DATABASE $(db)
 SET PARTNER = 'TCP://$(server):5092'
GO

SELECT db_name(sd.[database_id]) AS [Database Name],
 sd.mirroring_guid,
 sd.mirroring_state,
 sd.mirroring_state_desc,
 sd.mirroring_partner_name,
 sd.mirroring_witness_name,
 sd.mirroring_witness_state,
 sd.mirroring_witness_state_desc,
 sd.mirroring_role,
 sd.mirroring_role_desc,
 sd.mirroring_role_sequence,
 sd.mirroring_safety_level,
 sd.mirroring_safety_level_desc,
 sd.mirroring_safety_sequence,
 sd.mirroring_failover_lsn
FROM sys.database_mirroring AS sd
WHERE sd.[database_id] = db_id(N'$(db)')
GO

T-SQL Tuesday #025 – Truques


Este mês o Sr. Allen White (Blog | Twitter)  pediu para as pessoas dizerem quais truques elas utilizam para deixar o trabalho mais fácil…

Nós temos muitos códigos em powershell que ajudam a melhorar o dia, mas, powershell,,, aahh,,, se você usar o google, poderá encontrar muita gente escrevendo bons códigos que podem ajudá-lo.

Eu escrevi uma coisa legal, mas em T-SQL, para criar bases em mirror,,, Sim, eu sei, você pode encontrar um monte de blogs falando sobre como criar esse tipo de ambiente,,, mas eu vou fazer isso usando SQLCMD dentro do Management Studio,,, por quê? só pela diversão…

Eu vou pular a parte da criação dos end-poins porque você já sabe…

A parte legal está logo depois da versão em inglês,,,

Hi, i try translate all the text above, sorry if have some mistakes,,,

This month Mr. Allen White (Blog | Twitter) ask people to say what tricks we use to make our job easier…

We have a lot of code in powershell helping to improve the day, but, powershell,,, aahh,,, if you use the google will find a lot of people writing good scripts to help you.

I going to write some nice,, but in T-SQL, just to create a database mirror,,,, Yes, I know, you can find a lot of blogs talking about who to create a database mirror,,, but I will do this using the SQLCMD inside the Management Studio,, why? just for fun…

I´ll skip the creation of end-points because you already know…

The good part is here:


/* Change the principal server name and instance */
:SETVAR principal_server "SERVERNAME\INSTANCE1"
/* Change the mirror server name and instance */
:SETVAR mirror_server "SERVERNAME\INSTANCE2"
/* in this case I use the same server, but you can add one more setvar and add the other server */
:SETVAR server "SERVERNAME"
/* Database name to mirror */
:SETVAR db "DB_NAME"

:connect $(principal_server)

alter database $(db) set recovery full

backup database $(db)
to disk = 'D:\DB01\inst01\$(db).bak'
with compression, stats = 5

backup log $(db)
to disk = 'D:\DB01\inst01\$(db).trn'
with compression, stats = 5

go
:connect $(mirror_server)

restore database $(db)
from disk = 'D:\DB01\inst01\$(db).bak'
with file = 1,
move '$(db)' to 'D:\DB01\local\$(db).mdf',
move '$(db)_log' to 'D:\DB01\local\$(db).ldf',
norecovery, nounload, stats = 5

restore database $(db)
from disk = 'D:\DB01\inst01\$(db).trn'
with norecovery, nounload, stats = 5

alter database $(db)
set partner = 'TCP://$(server):5022'
go

:connect $(principal_server)

/* In this part you can change the setvar if was created other one */
alter database $(db)
set partner = 'TCP://$(server):5023'

 

Corrompendo um Banco SQL


Qual a necessidade de criar uma base corrompida?

Pra que você precisa desse tipo de coisa?

Você precisa treinar…

Mesmo que saiba o que fazer, é importante treinar para situações complicadas…

É melhor fazer muita tentativa em erro em um ambiente controlado do que no ambiente de produção,,, certo?

Então,,, antes de mais nada… eu sei que você sabe,,, mas não custa nada relembrar,,,

NUNCA FAÇA ISSO EM PRODUÇÃO !!!

Bom,,, com isso em mente,,, vamos começar,,,

1. Vamos criar uma base:

CREATE DATABASE [corrompeu]
GO

2. Vamos alterar o modo de recovery da base:

alter database corrompeu
set recovery full
GO

3. Agora vamos colocar uma tabela:

use corrompeu
GO

create table vendas
(
vendasID int identity,
clienteID int default convert(int, 100000 * RAND()),
vendaData datetime default getdate(),
vendaTotal money
)
GO

4. Adicionamos um índice pra dar gosto…

create clustered index vendaCI on vendas (vendasID)
GO

5. Colocamos uns dados,,,

set nocount ON
GO

declare @conta INT
select @conta = 0
while (@conta < 50000)
begin
    insert into
vendas (vendaTotal)
    values (100*RAND())
    select @conta = @conta +1
end
GO

7. E vamos fazer uns backups

use master
GO

backup database corrompeu
to disk = ‘d:\db01\local\corrompeu_1.bak’
with init
go

backup log corrompeu
to disk = ‘d:\db01\local\corrompeu_2.trn’
go

8. Bom,,, com os backups feitos,,, vamos ver as páginas que foram criadas,,,

dbcc ind (‘corrompeu’,‘vendas’,1)
GO

9. Escolha uma página e coloque no lugar do XXXXX

DBCC TRACEON (3604)
GO
dbcc page
(‘corrompeu’,1,XXXXX,3)

Você deve ver alguma coisa do tipo:

dbcc

A página que eu escolhi foi a 1:493. Meu vendasID vai do registro 24256 até 245000.

Agora começa a ficar legal….

10. Vamos colocar a base offline:

alter database corrompeu
set offline
GO

11. Agora um simples cálculo…

select 493*8192
GO

Temos o número em decimal da localização da página no arquivo .mdf

12. Com esse número vamos utilizar um editor Hexadecimal para achar a linha dentro do arquivo .mdf.

  • Dentro do editor de Hexadecimal, abra o arquivo .mdf (neste caso D:\DB01\Corrompeu.mdf).
  • Clique em “Localizar” e escolha “Ir Para”.
  • Escolha a opção “DEC”, digite ou cole o resultado do cálculo acima e depois cliente em “HEX”, ele vai converter o valor para Hexadecimal.

localizar

  • clique em “OK”
  • Altere a linha onde o cursor esta piscando para 00 (zero-zero), ela vai ficar em vermelho.

alterado

  • Salve o arquivo.

13. Agora dentro do SQL vamos voltar com a base online:

alter database corrompeu
set online
GO

14. Usando o DBCC CHECKDB, vamos ver se a base está realmente corrompida…

dbcc check

Legal,,, temos uma base corrompida…

15. vamos tentar um select na tabela,,, e olha lá o erro,,,

select

Bom,,, legal… temos uma base corrompida,,, e agora?

Agora fica legal… o objetivo é deixar a base operacional sem perder informação… imagine que essa é sua base de produção e justamente essa tabela é a folha de pagamento,,, olha que legal…

Uma dica: tentei fazer o processo de restore no SQL Server Denali CTP 1 e não consegui restaurar apenas a página, tive que remover ela e reinserir os dados através de outra base, fiz o mesmo processo de restore apenas da página no SQL Server 2008 R2 e funcionou sem problema.

Se alguém precisar de ajuda é só deixar o comentário…

ATUALIZAÇÃO:

Segue o link do SkyDrive com a base, backup e o script desse exemplo:

https://skydrive.live.com/?cid=5145b04265f2979d&sc=documents&id=5145B04265F2979D%21171#

TOP 5 – Ferramentas grátis


ATUALIZAÇÃO !!! – 20/09/2012

Esse post é para falar de ferramentas gratuitas,,, é com muito pesar que estou retirando o SSMS Tools Pack do primeiro lugar, a partir da versão 2.5.0.0 ele deixou de ser de graça, logo, vai contra o intuito do post…

Estou substituindo pela ferramenta SSMSBoost

Tem gente que gosta de fazer as coisas na marra,,, sem ajuda de nada,,, script de baixo de script,,, Isso é muito legal, tem muita coisa que só se resolve assim,,,

O importante é conhecer o que o mercado oferece quando você quer “uma ajuda” ou pra realmente facilitar o dia a dia,,,

O meu TOP 5 de ferramentas gratuitas são:

  1. Pra quem gosta de trabalhar com o SSMS, um add-on bem legal é o SSMS Tools Pack desenvolvido por Mladen Prajdić. Ele adiciona algumas funções bem legais como: histórico, snippets, gerador de código… Acho uma ferramenta pequena e legal… Uma ferramenta muito interessante para adicionar funcionalidades ao SSMS é o SSMSBoost ele adicionar recursos muito bons como snippets, localizador de objetos, alterador de barra de titulo e uma coisa bem legal que é o cadastro de conexão onde você pode colocar alerta de ambiente de produção,,, ai ele avisa, dependendo do comando que você precisa prestar atenção antes de dar um truncate table por exemplo…. Ele é de graça, mas naquelas, você precisa reinstalar ele a cada 45 dias (não é trial, é só uma coisa chata que o desenvolvedor colocou),,,
  2. Quem nunca passou raiva com o gerador de plano de execução do SSMS que drop um banco?,,, Se você usar o SQL Sentry Plan Explorer pelo menos uma vez, não vai querer deixar de usar,,, ele mostra de uma forma fácil de entender qual parte do plano estásendo mais custoso para a operação… fora outras coisas legais…
  3. Não pode faltar de jeito nenhum o Who is Active desenvolvido por Adam Machanic e por falar nele, existe um add-on da Schema Solutionsque adiciona uma interface gráfica para a execução de procedure.
  4. Na primeira vez que vi essa ferramenta não achei que seria tão útil, mas o SQL Trace Analyzeré bem interessante. Ele analisa o Profiler capturado em arquivo ou banco e gera um relatório consolidado mostrando o impacto, tempo, processamento, IO, etc.. E de brinde ele instala um monitorador de Locks/Blocks. O problema dessa ferramenta é a parafernália que ele instala, mas você pode remover o resto das coisas e ficar só com o programa principal.
  5. E não podia faltar alguma forma de monitorar o que acontece com o banco,,, para isso achei o IgniteFree, uma ferramenta muito simples de configurar e com muita informação relevante. Claro que a versão Trial/Full tem mais opções, mas mesmo na versão free é uma ótima ferramenta. Ela é leve, não ocupa muito espaço, não gera pressão na máquina que está sendo monitorada e de quebra ainda consegue monitorar uns Oracles que você tenha perdido no ambiente…

Movimentar arquivos de Bancos de Dados


Nesse post vou falar como movimentar os arquivos de um banco de dados de uma unidade/diretório para outra unidade/diretório.

Ai você pensa:

“Pra que? Já sei como faz isso. Não tem nenhuma novidade.” ou

“Aaahh,,, isso é facil, uso o bom e velho backup/restore ou o detach/attach…”

Isso é verdade, não tem nenhuma grande novidade em fazer a movimentação mas, ai vem a parte divertida, pra que fazer do método fácil se podemos fazer do método interessante?

1.- Backup/Restore

Se executarmos o bom e velho backup/restore, no momento do restore podemos alterar o caminho onde os arquivos irão ser gravados, isso é simples.

Apenas precisaremos executar o processo de backup que, dependendo do tamanho da base, pode demorar alguns minutos ou até umas horas. Além de ter que ter um espaço para armazenar o backup ou executá-lo através de uma unidade de backup.

2.- Detach/Attach

Usando o Detach ganhamos algum tempo, você vai apenas mover os arquivos de log e dados para outro lugar e anexar a base novamente.

O problema disso é se você usar o Service Broker ou até o Mirror, você terá que refazer o processo.

3.- Alter Database (o “método interessante”)

Esse “método” a seguir cria uma procedure para executar a movimentação do banco para outro local usando o Alter database, mas é possível executá-lo em diversos bancos como vou demonstrar:

Vamos criar 2 bases de dados para testar:

create database banco1

create database banco2

Agora execute o scritp abaixo para criar a procedure que irá executar a movimentação dos arquivos:

IF ( OBJECT_ID(‘dbo.sp_MoveDatabase’) IS NOT NULL )
begin
DROP PROCEDURE dbo.sp_MoveDatabase
end
GO

create procedure sp_MoveDatabase

@NewDataFolder nvarchar(1000),
@NewLogFolder nvarchar(1000),
@DbList nvarchar(4000)

as
Begin
declare @DbTable table (lkey int identity (1,1) primary key, dbname nvarchar(100))
declare @FileTable table (lkey int identity (1,1) primary key, [name]nvarchar(100), physical_name nvarchar(1000), [type] int )
declare @sql nvarchar(4000)
declare @count int, @RowNum int
declare @DbName nvarchar(100)
declare @OldPath nvarchar(1000)
declare @Type int
declare @LogicalName nvarchar(100)
declare @ParmDefinition nvarchar(1000)
declare @FileName nvarchar(100)
declare @NewPath nvarchar(1000)
declare @ShowAdvOpt int
declare @XPCMD int

set nocount on;

if right(@DbList,1) = ‘,’

Begin
print ‘DbList must NOT end with “””‘
return

End
declare @MyString NVARCHAR(100)
declare @Pos INT
declare @NextPos INT
declare @String NVARCHAR(4000)
declare @Delimiter NVARCHAR(1)

set @String = @DbList
set @Delimiter = ‘,’
SET @String = @String + @Delimiter
SET @Pos = charindex(@Delimiter,@String)
WHILE (@pos <> 0)

BEGIN
SET @MyString = substring(@String,1,@Pos – 1)
insert into @DbTable (dbname) values (LTRIM(RTRIM(@MyString)))
SET @String = substring(@String,@pos+1,len(@String))
SET @pos = charindex(@Delimiter,@String)

END
set @ShowAdvOpt = cast(( select [value] from sys.configurations where [name] = ‘show advanced options’) as int)
set @XPCMD = cast(( select [value] from sys.configurations where [name] = ‘xp_cmdshell’) as int)
if right(@NewDataFolder,1)<> ‘\’ or right(@NewLogFolder,1)<>’\’

Begin
print ‘new path”s must end with \’
return
end
EXEC sp_configure ‘show advanced option’, ’1′
RECONFIGURE

exec sp_configure ‘xp_cmdshell’ , ’1′
RECONFIGURE

print ‘NewMdfFolder is ‘ + @NewDataFolder
print ‘NewLdfFolder is ‘ + @NewLogFolder

SET @RowNum = 1
SET @count = (select count(*) from @DbTable)
while @RowNum <= @count

Begin
select @DbName = DBName from @DbTable
where lKey = @RowNum
set @sql = ‘select name, physical_name, type from ‘ + @DbName + ‘.sys.database_files’
insert into @FileTable
exec sp_executesql @sql

– Derruba todas as conexoes configurando como single user with immediate
set @sql= ‘ALTER DATABASE [' + @DbName + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE’
print ”
print ‘Executando linha -’ + @sql
exec sp_executesql @sql

– configura db off line
set @sql = ‘ALTER DATABASE [' + @DbName + '] SET OFFLINE;’
print ”
print ‘Executando linha – ‘ + @sql
exec sp_executesql @sql
select * from @FileTable
while @@rowcount > 0

begin
select top 1 @OldPath = physical_name, @Type = [type], @LogicalName = [name] from @FileTable

–move arquivos files
set @FileName = (SELECT REVERSE(SUBSTRING(REVERSE(@OldPath), 0, CHARINDEX(‘\’, REVERSE(@OldPath), 1))))
if @type = 0

begin
set @NewPath = @NewDataFolder + @FileName
end
else
begin

set @NewPath = @NewLogFolder + @FileName
end
set @Sql = ‘EXEC master..xp_cmdshell ”MOVE “‘ + @OldPath + ‘” “‘ + @NewPath +’””’
print ”
print ‘Executando linha -’ + @sql
exec sp_executesql @sql

– altera caminho dos arquivos
set @sql = ‘ALTER DATABASE ‘ + @DbName + ‘ MODIFY FILE (NAME = ‘ + @LogicalName + ‘, FILENAME = “‘ + @NewPath + ‘”)’
exec sp_executesql @sql
delete from @FileTable where [name] = @LogicalName
select * from @FileTable
end –while

set @sql = ‘ALTER DATABASE [' + @DbName + '] SET ONLINE;’
print ”
print ‘Executing line -’ + @sql
exec sp_executesql @sql
SET @RowNum = @RowNum + 1

– aceita multi user novamente.
set @sql= ‘ALTER DATABASE [' + @DbName + '] SET MULTI_USER’
print ”
print ‘Executing line -’ + @sql
exec sp_executesql @sql
end
exec sp_configure ‘xp_cmdshell’ , @XPCMD

reconfigure
EXEC sp_configure ‘show advanced option’, @ShowAdvOpt

RECONFIGURE
End –procedure

** ATENÇÃO **

Os diretórios de destino já devem estar criados, caso você execute a procedure sem criar o destino o script vai alterar o caminho da base e não vai movimentar os arquivos e quando ela foi trazida online ela vai apresentar erro.

** ATENÇÃO 2 **

Esse script é do tipo “Vai filhão”, quando ele for executado todos os usuários conectados serão desconectados sem dó nem piedade, todas as transações que eles estiverem executando serão dropadas. As conexões apenas poderão ser reestabelecidas após o termino da movimentação.

Para executar a procedure execute-a da seguinte forma:

exec sp_MoveDatabase @NewDataFolder = ‘c:\teste\’, @NewLogFolder = ‘d:\teste\’, @sDbList = ‘banco1, banco2′

Se tudo der certo, as bases banco1 e banco2 estarão seus novos destinos.