Olá pessoal.
Hoje, vou compartilhar um dos scripts que escrevi e utilizo no meu ambiente (Migrações, atualização de ambientes, plano de Disaster Recovery).
Esta stored procedure busca no diretório informado por arquivos de uma determinada extensão e retorna os respectivos nomes físicos, podendo ser para um arquivo ou todos os arquivos ali contidos.
Script
-- ============================ -- -- Title: Search Backup Archive -- -- Type: Stored Procedure -- -- Author: Leandro Ribeiro -- -- Create Date: 18/08/2011 -- -- ============================ -- -- Twitter: @sqlleroy -- -- blog: sqlleroy.com -- -- ============================ -- USE master GO IF OBJECT_ID('[prd_SearchBackupArchive]') IS NOT NULL DROP PROC [prd_SearchBackupArchive] GO CREATE PROC [prd_SearchBackupArchive]( @Database VARCHAR(30) ,@Extension CHAR(4) ,@PathBackup VARCHAR (100) ,@DbSystem CHAR(1) -- Find backup archives with a last modified date less than or equal to the current date minus "@SeekDaysAgo" days. ,@SeekDaysAgo VARCHAR(3) ,@LastBackup VARCHAR(100) OUTPUT ) AS BEGIN SET NOCOUNT ON; SET QUOTED_IDENTIFIER ON; SET ANSI_WARNINGS ON; DECLARE @Command VARCHAR(1000) ,@Error VARCHAR(100) DECLARE @Forfiles TABLE (CMD VARCHAR(200)) -- ======================= -- -- Create temporary tables -- -- ======================= -- IF OBJECT_ID ('tempdb..##ArqBck') IS NOT NULL DROP TABLE ##ArqBck CREATE TABLE ##ArqBck (PhysicalName VARCHAR(100), DatabaseName SYSNAME, DayTime VARCHAR(15)) IF OBJECT_ID ('tempdb..#Forfiles') IS NOT NULL DROP TABLE #Forfiles CREATE TABLE #Forfiles (CMD VARCHAR(200)) -- ============================================================ -- -- MS-DOS Command for returning contained archives in directory -- -- ============================================================ -- IF @Database = '' SELECT @Command = 'forfiles /P ' + @PathBackup + CASE WHEN @SeekDaysAgo > 0 THEN ' /D -' + @SeekDaysAgo ELSE '' END + ' /M *' + @Extension + ' /C "cmd /c echo @file"'; ELSE SELECT @Command = 'forfiles /P ' + @PathBackup + CASE WHEN @SeekDaysAgo > 0 THEN ' /D -' + @SeekDaysAgo ELSE '' END + ' /M ' + @Database + '*' + @Extension + ' /C "cmd /c echo @file"'; EXEC sp_configure 'show advanced options', 1 RECONFIGURE WITH OVERRIDE EXEC sp_configure 'xp_cmdshell', 1 RECONFIGURE WITH OVERRIDE INSERT INTO #Forfiles EXEC xp_cmdshell @Command EXEC sp_configure 'xp_cmdshell', 0 RECONFIGURE WITH OVERRIDE EXEC sp_configure 'show advanced options', 0 RECONFIGURE WITH OVERRIDE SELECT @Error = CMD FROM #Forfiles WHERE CMD LIKE 'ERRO:%' IF @Error <> '' BEGIN SELECT @Error RAISERROR (@Error,10,1) DROP TABLE ##ArqBck END ELSE BEGIN -- Adjusting the field to facilitate the subsequent writing UPDATE #Forfiles SET CMD = REPLACE(CMD,'"','') -- =============================== -- -- Store result in temporary table -- -- =============================== -- SELECT @Command = 'INSERT INTO ##ArqBck SELECT CMD PhysicalName, SUBSTRING(CMD, 0,CHARINDEX(''_backup'',CMD)) DatabaseName, CASE CONVERT(VARCHAR(2),SERVERPROPERTY(''productversion'')) WHEN 9 THEN REPLACE(SUBSTRING(CMD, CHARINDEX(''_backup'',CMD) +7 ,13),''_'','''') ELSE REPLACE(SUBSTRING(CMD, CHARINDEX(''_backup'',CMD) +8 ,15),''_'','''') END DayTime FROM #Forfiles WHERE CMD IS NOT NULL' + CHAR(13) -- Whenever want exclude system databases when search all databases IF @DbSystem = 'N' AND @database = '' SELECT @Command = @Command + ' AND SUBSTRING(REPLACE(CMD,''"'',''''), 0,CHARINDEX(''_backup'',REPLACE(CMD,''"'',''''))) NOT IN (''master'',''msdb'',''model'',''tempdb'')' EXEC (@Command) -- ================== -- -- Index result table -- -- ================== -- IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = 'IX_ArqBck') CREATE NONCLUSTERED INDEX IX_ArqBck ON ##ArqBck (DayTime, DatabaseName) INCLUDE (PhysicalName) -- Return last backup name the database IF @Database <> '' SELECT @LastBackup = PhysicalName FROM ##ArqBck ORDER BY DayTime ASC END END EXEC sys.sp_MS_marksystemobject '[prd_SearchBackupArchive]' go
Image may be NSFW.
Clik here to view.
- Retorno da procedure prd_SearchBackupArchive
Clik here to view.

Arquivos de backups no diretório.
O script está ajustado ao padrão de nome do arquivo de backup utilizado pelo plano de manutenção nativo do SQL Server.
Para utilizar a procedure, devemos ter permissões para:
- Alterar as configurações do sql (sp_configure).
- Executar o comando xp_cmdshell
- Permissão de leitura no diretório informado.
Perceba que a procedure habilita o comando xp_cmdshell e tão logo o execute, o recurso é desabilitado.
Como não é recomendável (por questões de segurança) que o comando xp_cmdshell esteja habilitado, esta é uma forma de atenuar possíveis problemas.
Se tiver recomendações de ajustes no script, fique a vontade para comentar… Afinal, críticas construtivas são sempre bem vindas.
No próximo post, vou compartilhar outra procedure que gera o comando de restore dinamicamente utilizando esta procedure.
Como este é meu último post no ano de 2012, desejo a todos um ano novo de saúde , realizações pessoais e profissionais.
Até o próximo post.
Image may be NSFW.
Clik here to view.
Clik here to view.
