Technical Article

Automatic Backups

,

Creates the backup devices where sql server is installed, creates an error message above 50001, an alert, and an adittional job in case the scripts fails. In the first time backups all databases and then backups the logs until two days past from the last full backup. Then backups the databases again and so on.

You can create a job to run the script by EXEC master..xp_cmdshell 'osql -Usa -P -ic:\....\script.sql'

The comments are in Spanish, because I'm from Argentina. I didn't wanted to translate it, sorry.

/*	
**Autor:Rodrigo G. Acosta racosta@iecisa.com.ar
**Fecha:07/08/01
**Ultima modificacion:23/08/01
**El script se ejecuta automaticamente por un Job que se crea en la instalacion,
**actualmente esta configurado para que lo
**ejecute el SA sin password. Si en el futuro se cambia
**la password, el script no se ejecutara.
*/




SET NOCOUNT ON

USE master

--Imprime datos para que queden acentados en el script de LOG
PRINT ' '
PRINT '----------------------------'
PRINT '|Fecha='+CONVERT(VARCHAR(20),getdate())+' |' --Fecha de ejecucion
PRINT '|Usuario='+suser_sname()+'                |' --Usuario que ejecuto
PRINT '|Servidor='+@@servername+'     |'	    --Servidor donde corre el script	
PRINT '----------------------------'
PRINT ''
PRINT @@version  --Version de SQL Server
PRINT ''

/*---------------------------------------------------------------------------------------------
**Comienza a chequear si existe la base LOG_BACKUP 
**que guardara todas las transacciones de backup
**Si no existe la crea. Luego chequea que existan
**las tablas que guardan los registros, si no existen
**los crea.
----------------------------------------------------------------------------------------------*/


	/*
	**Declara las variables que se utilizan
	**para crear la base de datos log_backup
	**en la direccion fisica donde estan instaladas
	**las demas bases de datos. Las variables utilizadas
	**aqui solamente se utilizan para la creacion de la 
	**base. Para los backup device se utilizan las variables
	**@path, @lenght y @numero que se declaran mas abajo.
	*/

	DECLARE @path_db VARCHAR(200)
	DECLARE @lenght_db VARCHAR(400)
	DECLARE @numero_db VARCHAR(2)

	IF NOT EXISTS
			(SELECT name
			FROM sysdatabases
			WHERE name='log_backup')

			BEGIN
				set @lenght_db=(
						select filename
						from master..sysfiles
						where name='master'
						)
				set @path_db=(
						select filename
						from master..sysfiles
						where name='master'
						)
				set @lenght_db=LEN (@lenght_db)
				set @numero_db=@lenght_db-10
				SET @path_db= left(@path_db,@numero_db)

				DECLARE @dbcreation varchar(400)
				SET @dbcreation='CREATE DATABASE log_backup
				ON PRIMARY
				(NAME="log_backup_data",
				FILENAME="'+@path_db+'log_backup.mdf",
				SIZE=1MB,
				FILEGROWTH=1MB)
				LOG ON
				(NAME="log_backup_log",
				FILENAME="'+@path_db+'log_backup.ldf",
				SIZE=1MB,
				FILEGROWTH=1MB)'
				EXEC(@dbcreation)
				PRINT 'Se ha creado la base log_backup de auditoria'
			END
GO
/*
**Una vez creada la base chequea si existen
**las tablas. Si no existen las crea.
*/


		IF EXISTS  
			  (SELECT name
			   FROM sysdatabases
			   WHERE name='log_backup')
		AND
		NOT EXISTS
			(select name
			FROM log_backup..sysobjects
			WHERE name='backup_log'
			AND
			xtype='u')	
				BEGIN				
					CREATE TABLE log_backup..backup_log
					(lid numeric(5) identity(1,1) not null,
					fecha varchar(30) not null,
					nombre varchar(40) not null,
					descripcion varchar(100) not null,
					completo char(2) not null)
		
					CREATE TABLE log_backup.dbo.sysdb
					(lid numeric(5) identity(1,1) not null,
					fecha varchar(30) not null,
					nombre varchar(40) not null,
					descripcion varchar(100) not null,
					completo char(2) not null)
		
					CREATE TABLE log_backup.dbo.userdb
					(lid numeric(5) identity(1,1) not null,
					fecha varchar(30) not null,
					nombre varchar(40) not null,
					descripcion varchar(100) not null,
					completo char(2) not null)
		
					CREATE TABLE log_backup.dbo.backup_device
					(lid numeric(5) identity(1,1) not null,
					fecha varchar(30) not null,
					nombre varchar(40) not null,
					path varchar(100) not null,
					completo char(2) not null)
					PRINT ' Se han creado las tablas de la base de auditoria'		

			END

/*---------------------------------------------------------------------------------------------
**Finaliza con la creacion de la base
** y las tablas.
----------------------------------------------------------------------------------------------*/



GO
/*
**Comienza la declaracion de las variables
*/

DECLARE @cmd_userdb varchar(200)	--Guarda la ejecucion del backup de userdb
DECLARE @cmd_sysdb varchar(200)		--Guarda la ejecucion del backup de sysdb
DECLARE @cmd_log varchar(255)		--Guarda la ejecucion del backup de logs
DECLARE @devices VARCHAR(100)		--Guarda los nombres de los devices
DECLARE @path VARCHAR(200)		--Guarda la direccion fisica del backup device
DECLARE @sysdatabases VARCHAR(70)	--Guarda los nombres de las bases del sistema
DECLARE @databases VARCHAR(70)		--Guarda los nombres de las bases de usuarios
DECLARE @faltanuserdb varchar(20)	--Guarda el tiempo que falta en las bases de usuarios desde el ultimo backup
DECLARE @faltansysdb varchar(20)	--Guarda el tiempo que falta en las bases del sistema desde el ultimo backup
DECLARE @raiserror varchar(40)          --Guarda la sintaxis de ejecucion del raise error
DECLARE @last_error_no numeric(5)       --Guarda el ultimo numero de error configurable para crear el error
DECLARE @lenght VARCHAR(400)		--Guarda la cant. de caracteres que tiene el path fisico de los backup device
DECLARE @numero VARCHAR(2)		--Guarda la cant. de caracteres que se restan para cortar el path 

/*
**Finaliza la declaracion de variables
*/




/*
**Chequea si existe el mensaje de error que se utiliza durante la ejecucion 
**del script. Si no existe, lo crea.
*/

IF NOT EXISTS (
		SELECT *
		FROM SYSMESSAGES
		WHERE description LIKE 'El script de Backup de todas las bases del servidor fallo por un error desconocido%'
		)

		BEGIN
			DECLARE @addmessage varchar(300) --Guarda la sintaxis para agregar el mensaje
			IF (
				/*Chequea si existe algun error de usuario configurado anteriormente*/
				SELECT TOP 1 error 
				FROM sysmessages
				ORDER BY error DESC)<50000
				BEGIN
					SET @last_error_no=50001 --Si no se creo ningun error
				END				 --le asigna el valor 50001
			ELSE
				BEGIN
			/*Si ya existe un mensaje de usuario, crea otro con una unidad mas*/	
				SET @last_error_no=(
					SELECT TOP 1 error 
					FROM sysmessages
					ORDER BY error DESC
								)+1 
				END				    
			/*Se guarda la sintaxis del comando sp_addmessage y se ejecuta*/
			SET @addmessage='EXEC sp_addmessage @msgnum='+CONVERT(VARCHAR(5),@last_error_no)+
					',@severity=16,@lang="us_english",@msgtext="El script de Backup de todas las bases del servidor fallo por un error desconocido. Se iniciará automaticamente un JOB predefinido que backupeara todas las bases de datos del sistema.",
					@with_log=true'

			EXEC (@addmessage)--Se agrega el mensaje con severidad 16 y with_log
			/*Se imprime mensaje especificando los datos del nuevo mensaje de error*/
			PRINT 'Se ha creado un nuevo mensaje de error del servidor con el numero '+CONVERT(VARCHAR(5),@last_error_no)

			/*Se guarda la sintexis del raiserror que se utiliza para levantar el error recien creado*/
			SET @raiserror='RAISERROR ('+CONVERT(VARCHAR(5),@last_error_no)+',16,1) WITH LOG'
		END
ELSE --Si ya existe lo indica y ajusta la variable que guarda el numero de error
		BEGIN
			PRINT 'El mensaje de error utilizado aqui ya existe. No hace falta crearlo'
			SET @last_error_no=(
						SELECT  error 
						FROM sysmessages
						WHERE description='El script de Backup de todas las bases del servidor fallo por un error desconocido. Se iniciará automaticamente un JOB predefinido que backupeara todas las bases de datos del sistema.'
									)
			SET @raiserror='RAISERROR ('+CONVERT(VARCHAR(5),@last_error_no)+',16,1) WITH LOG'
			
		END
/*
**Termina con la creacion del mensaje 
*/


/*
**Creacion del job de respaldo
**que se utiliza para realizar
**un backup en caso de que el
**script falle. Es lanzado por
**una alerta que se ejecuta por
**el mensaje creado anteriormente
*/

IF NOT EXISTS
		(
		SELECT job_id
		FROM   msdb.dbo.sysjobs    
		  WHERE (name = N'Backup full ante falla de script de backup')     
										)  
	BEGIN

		  DECLARE @JobID BINARY(16)  
		  DECLARE @ReturnCode INT    

	
		  -- Add the job
		  EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT , @job_name = N'Backup full ante falla de script de backup', @owner_login_name = N'sa', @description = N'No description available.', @category_name = N'[Uncategorized (Local)]', @enabled = 1, @notify_level_email = 0, @notify_level_page = 0, @notify_level_netsend = 0, @notify_level_eventlog = 2, @delete_level= 0
 

		  -- Add the job steps
		  EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = N'backup full por falla de script de backup', @command = N'DECLARE @databases varchar(40)
DECLARE @cmd_userdb varchar(300)
DECLARE db_cursor CURSOR		--Declaracion del cursor

FOR
/*Guarda los nombre de las bases sin incluir las del sistema y las de prueba*/
		SELECT name 
		FROM sysdatabases	
		WHERE name NOT IN 	(''master'',
					''northwind'',
					''pubs'',
					''model'',
					''tempdb'',
					''msdb'',
					''prueba'')
OPEN db_cursor

FETCH NEXT FROM db_cursor INTO @databases
WHILE (@@FETCH_STATUS=0) 		--Chequea que no haya error de fetch
		BEGIN



				SET @cmd_userdb=(''BACKUP DATABASE '' + @databases + '' TO backup_'' + @databases +
						 '' WITH INIT, NAME="Backup del job por falla critica del dia '' + 
						CONVERT(VARCHAR(20),getdate())+''"''+
						'',DESCRIPTION="Backup del job por falla critica"'')

				EXEC  (@cmd_userdb)
		FETCH NEXT FROM db_cursor INTO @databases
		END
	


', @database_name = N'master', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 0, @retry_attempts = 3, @retry_interval = 1, @output_file_name = N'', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 2

  EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1 


  -- Add the Target Servers
  EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)' 

	PRINT 'Se ha creado un job que se utilizara en caso de falla del script'
	PRINT ' '

	END

ELSE --Si ya existe lo indica
	BEGIN
		PRINT 'El job de respaldo del script de backup ya existe.Continuando...'
		PRINT ' '
	END

/*
**Fin de Creacion del job de backup
*/




/*
**Creacion de la alerta que ejecuta
**el job anterior en caso de error
*/
IF NOT EXISTS
		(
		SELECT name 
		FROM msdb.dbo.sysalerts 	
		WHERE name = N'Alerta por falla de script de backup'
									)
	BEGIN
		EXECUTE msdb.dbo.sp_add_alert @name = N'Alerta por falla de script de backup', @message_id = @last_error_no, @severity = 0, @enabled = 1, @delay_between_responses = 60, @include_event_description_in = 5, @job_name = N'Backup full ante falla de script de backup', @category_name = N'[Uncategorized]'
		PRINT 'Se ha creado una alerta que ejecutara el job de respaldo en caso de error del script'
		PRINT ''
	END
ELSE --Si ya existe lo indica
	BEGIN
	PRINT 'La alerta de respaldo ya existe.Continuando...'
	PRINT ' '
	END
/*
**Fin creacion alerta
*/





/*
**Declara el cursor que guardara los nombres
**de las bases de usuarios
**/

DECLARE db_cursor CURSOR		

FOR

		SELECT name 
		FROM sysdatabases	
		WHERE name NOT IN 	('master',
					'northwind',
					'pubs',
					'model',
					'tempdb',
					'msdb') --Saca del cursor las del sistema


------------------------------------------------------------------------------------------------

				   --BACKUP LOG FROM USER DATABASES

------------------------------------------------------------------------------------------------

OPEN db_cursor --Abre el cursor con los nombres de las bases

FETCH NEXT FROM db_cursor INTO @databases
WHILE (@@FETCH_STATUS=0) 		--Chequea que no haya error de fetch

/*Si hay algun error con el fetch del cursor aborta la transaccion y hace un rollback*/
	IF (@@FETCH_STATUS<>0)
		BEGIN
			PRINT 'Ha ocurrido un error'
			ROLLBACK TRAN
			/*Ejecuta el raise error que levanta el mensaje creado antes*/
			EXEC (@raiserror) 
			RETURN
		END
	ELSE
		BEGIN			
/*
**Chequea que ninguna base este con la opcion de trunc. log on chkpt. habilitada
** si es asi la deshabilita para realizar los backups
*/
      IF EXISTS 
		(select  v.name
	         from master.dbo.spt_values v, master.dbo.sysdatabases d
        	    where d.name=@databases
	            and ((number <> 0
		    and number not in (-1) 
                    and v.type = 'D'
                    and (v.number & d.status)=v.number)
		    and v.name='trunc. log on chkpt.'))
		BEGIN
			EXEC sp_dboption @databases,'trunc. log on chkpt.',false --Deshabilita la opcion
			PRINT 'Se cambio la opcion de trunc. log on chkpt en la base '+@databases --Imprime el mensaje de OK
		END

	ELSE
		BEGIN
		PRINT 'La configuracion de la base "'+@databases+'" permite hacer backups...continuando' --Imprime mensaje OK
		END


				/*Guarda en @cmd_log la sitaxsis del comando backup log para las bases*/
				SET @cmd_log=('BACKUP LOG '+@databases + ' ' + 
				'TO backup_' + @databases + ' ' +		
				'WITH NOINIT, NAME="Backup LOG del dia '+
				CONVERT(VARCHAR(30),GETDATE())+'"'+
				',DESCRIPTION="LOG cada 4 horas"')

/*
**Chequea si existen todos los backup devices necesarios para
**backupear las bases y si no crea uno nuevo
*/
			IF NOT EXISTS 
					(SELECT name FROM SYSDEVICES
					WHERE name like ("backup_"+@databases))
				
				/*Encuentra la direccion fisica donde esta instalado el motor y crea los backup device en esa direccion.*/
				BEGIN 
						SET @devices="backup_"+@databases
						set @lenght=(
								select filename
								from master..sysfiles
								where name='master'
								)
						set @path=(
								select filename
								from master..sysfiles
								where name='master'
								)
						set @lenght=LEN (@lenght)
						set @numero=@lenght-15
						SET @path= left(@path,@numero)+'backup\'+@devices+'.bak'
					


	/*Ejecuta el sp_addumpdevice*/	EXEC  SP_ADDUMPDEVICE @devtype='DISK',
					@logicalname=@devices,
					@physicalname=@path
					PRINT ' '
					PRINT 'Device '+@devices+' on '+@path+' added'--imprime el ok.
					PRINT ' '

/*Inserta en la tabla backup_device alguna modificacion*/

						INSERT log_backup.dbo.backup_device
						(fecha,nombre,path,completo)
						VALUES
						(getdate(),@devices,@path,'Si')

					PRINT 'Actualizando tabla log_backup..backup_device' --Imprime mensaje OK

/*Chequea el estado de la variable @@error avortando en caso de error*/
					IF @@error<>0
						BEGIN
							PRINT 'Ha ocurrido un error desconocido luego de verificar los backup devices'
							ROLLBACK TRAN
							INSERT log_backup.dbo.backup_device
							(fecha,nombre,path,completo)
							VALUES
							(getdate(),@devices,@path,'No')
							/*Ejecuta el raise error que levanta el mensaje creado antes*/
							EXEC (@raiserror) 				
							RETURN
		
						END

				END			

/*
**Para que un backup log sea util es necesario tener por lo menos un backup full de la base.
**Chequea si es el primer backup que se hace y realiza un backup full antes de hacer un
**backup del log. Consulta la tabla msdb..backupset donde figuran los backups realizados.
*/
IF NOT EXISTS
		(
		SELECT *
		FROM msdb..backupset
		WHERE type='D'
		AND
		database_name=@databases
		AND
		database_name NOT IN ('master','model','msdb'))
			BEGIN
				/*Guarda la sintaxis de ejecucion del backup inicial*/
				SET @cmd_userdb=('BACKUP DATABASE ' + @databases + ' TO backup_' + @databases +
						 ' WITH INIT, NAME="Backup primero del dia ' + 
						CONVERT(VARCHAR(20),getdate())+'"'+
						',DESCRIPTION="Backup full inicial"')		
				EXEC (@cmd_userdb)
				PRINT 'Se realizo el backup inicial de la base '+@databases+ ' para poder hacer un backup de los logs' --Imprime mensaje OK
				PRINT ''

						/*Guarda el registro en la base de auditoria*/
						INSERT log_backup.dbo.userdb
						(fecha,nombre,descripcion,completo)
						VALUES
						(getdate(),@databases,'Backup full inicial','Si')

					PRINT 'Actualizando tabla log_backup..userdb'
					PRINT ' '

					IF @@error<>0
						BEGIN
							PRINT 'Ha ocurrido un error desconocido al realizar el backup inicial'
							ROLLBACK TRAN
							INSERT log_backup.dbo.userdb
							(fecha,nombre,descripcion,completo)
							VALUES
							(getdate(),@databases,'Backup full inicial','No')
							/*Ejecuta el raise error que levanta el mensaje creado antes*/
							EXEC (@raiserror)							
							RETURN
		
						END

			END
/*
**Luego de chequear si es el primer backup realiza un backup de Log.
**Si se hiso un backup full, luego hace un backup log y si ya existe
**un backup full, realiza solamente el backup log.
*/

			EXEC  (@cmd_log) --Ejecuta el comando de backup log

/*Inserta en la tabla log_backup alguna modificacion*/		
			BEGIN
			INSERT log_backup.dbo.backup_log
			(fecha,nombre,descripcion,completo)
			VALUES
			(getdate(),@databases,'LOG cada 4 horas','Si')
			END
					
			PRINT 'Actualizando tabla log_backup'
/*Chequea el estado de la variable @@error avortando en caso de error*/
					IF @@error<>0
						BEGIN
							PRINT 'Ha ocurrido un error desconocido al ejecutar backup de logs'
							ROLLBACK TRAN
							INSERT log_backup.dbo.backup_log
							(fecha,nombre,descripcion,completo)
							VALUES
							(getdate(),@databases,'LOG cada 4 horas','No')
							/*Ejecuta el raise error que levanta el mensaje creado antes*/
							EXEC (@raiserror)
							RETURN
						END

/*Imprime Mensaje informativo del log backupeado*/
			PRINT '             ------Backup LOG '+ @databases+ ' completado-------' --Imprime OK.
			PRINT ' '

			FETCH NEXT FROM db_cursor INTO @databases --recomienza el fetch
		END
	
CLOSE db_cursor --Cierra el cursor que tiene la lista de las bases sin desalocarlo




------------------------------------------------------------------------------------------------

			            --BACKUP USER DATABASES

------------------------------------------------------------------------------------------------
OPEN db_cursor --Vuelve a abrir el cursor
FETCH NEXT FROM db_cursor INTO @databases
	WHILE (@@FETCH_STATUS=0)
	BEGIN

/*Si hay algun error con el fetch del cursor aborta la transaccion y hace un rollback*/
		IF (@@FETCH_STATUS<>0)
			BEGIN
				PRINT 'Ha ocurrido un error'
				ROLLBACK TRAN
				/*Ejecuta el raise error que levanta el mensaje creado antes*/
				EXEC (@raiserror)
				RETURN
			END
		ELSE



/*
**Guarda en la variable la cantidad de dias que pasaron desde el
**ultimo backup full que se hiso de las bases de usuarios.
*/
	SET @faltanuserdb=(SELECT TOP 1 CONVERT(SMALLDATETIME,GETDATE()) - CONVERT(SMALLDATETIME,backup_finish_date)   --Chequea si pasaron dos dias 
		FROM msdb.dbo.backupset		  --Desde el ultimo backup de cada base	
		WHERE database_name=@databases
		AND type='D'
		ORDER BY backup_finish_date DESC) 
/*
**Chequea la diferencia entre  el ultimo backup y la fecha actual. Si es mayor
**a dos dias, ejecuta el backup, sino sigue con el script
*/
	IF
		@faltanuserdb>CONVERT(SMALLDATETIME,'1900-01-03 00:00:00')
			BEGIN
				/*Guarda en la variable la sintaxis de ejecucion del backup*/
				SET @cmd_userdb=('BACKUP DATABASE ' + @databases + ' TO backup_' + @databases +
						 ' WITH INIT, NAME="Backup userdb del dia ' + 
						CONVERT(VARCHAR(20),getdate())+'"'+
						',DESCRIPTION="Backup userdb cada 2 dias"')

				EXEC  (@cmd_userdb) --Ejecuta el backup
			/*Inserta en la tabla USERDB alguna modificacion*/		
			BEGIN
			INSERT log_backup.dbo.userdb
			(fecha,nombre,descripcion,completo)
			VALUES
			(getdate(),@databases,'Backup userdb cada 2 dias','Si')
			END	
			PRINT 'Actualizando tabla USERDB'

					/*Chequea el estado de la variable @@error avortando en caso de error*/
					IF @@error<>0
						BEGIN
							PRINT 'Ha ocurrido un error desconocido al ejecutar backup de bases de usuarios'
							ROLLBACK TRAN
							INSERT log_backup.dbo.userdb
							(fecha,nombre,descripcion,completo)
							VALUES
							(getdate(),@databases,'Backup userdb cada 2 dias','No')
							/*Ejecuta el raise error que levanta el mensaje creado antes*/
							EXEC (@raiserror)
							RETURN
						END

				PRINT 'Backup Database '+ @databases+ ' completado' --Imprime OK.
				PRINT ' '

			END
/*
**Si todavia no hace falta hacer un backup
**Calcula cuanto tiempo que hace falta y lo indica.
*/
	ELSE
		IF @faltanuserdb<CONVERT(SMALLDATETIME,'1900-01-02 00:00:00')	
			BEGIN
			PRINT 'Falta un dia para hacer un backup de la base '+@databases
			PRINT ' '
			END
		ELSE
			BEGIN
			PRINT 'Faltan dos dias para hacer un backup de la base '+@databases
			PRINT ' '		
			END	


		FETCH NEXT FROM db_cursor INTO @databases --recomienza el fetch
		END
	

CLOSE db_cursor
DEALLOCATE db_cursor --cierra y deja libre el cursor.

------------------------------------------------------------------------------------------------

			            --BACKUP SYSTEM DATABASES

------------------------------------------------------------------------------------------------
DECLARE sysdb_cursor CURSOR		--Declaracion del cursor con las bases del sistema
FOR
		SELECT name 		--Coloca el nombre de las tablas
		FROM sysdatabases	--dentro del cursor sin incluir las del sistema.
		WHERE name  IN 		('master',
					'model',
					'msdb')
OPEN sysdb_cursor
FETCH NEXT FROM sysdb_cursor INTO @sysdatabases
WHILE (@@FETCH_STATUS=0)
BEGIN
/*Si hay algun error con el fetch del cursor aborta la transaccion y hace un rollback*/
	IF (@@FETCH_STATUS<>0)
		BEGIN
			PRINT 'Ha ocurrido un error'
			ROLLBACK TRAN
			/*Ejecuta el raise error que levanta el mensaje creado antes*/
			EXEC (@raiserror)
			RETURN
		END

/*
**Encuentra la direccion fisica donde esta instalado el motor y crea los backup device en
**esa direccion.
*/

	IF NOT EXISTS (
			SELECT name
			FROM master..sysdevices
			WHERE name='backup_'+@sysdatabases
			)
		BEGIN
			SET @devices='backup_'+@sysdatabases
			set @lenght=(
					select filename
					from master..sysfiles
					where name='master'
					)
			set @path=(
					select filename
					from master..sysfiles
					where name='master'
					)
			set @lenght=LEN (@lenght)
			set @numero=@lenght-15
			SET @path= left(@path,@numero)+'backup\'+@devices+'.bak'

	/*Ejecuta el sp_addumpdevice*/	EXEC  SP_ADDUMPDEVICE @devtype='DISK',
					@logicalname=@devices,
					@physicalname=@path
					PRINT ' '
					PRINT 'Device backup_'+@sysdatabases+' on '+@path+' added'--imprime el ok.
					PRINT ' '

/*Inserta en la tabla backup_device alguna modificacion*/

						INSERT log_backup.dbo.backup_device
						(fecha,nombre,path,completo)
						VALUES
						(getdate(),'backup_'+@sysdatabases,@path,'Si')

					PRINT 'Actualizando tabla log_backup..backup_device'

/*Chequea el estado de la variable @@error avortando en caso de error*/
					IF @@error<>0
						BEGIN
							PRINT 'Ha ocurrido un error desconocido luego de verificar los backup devices'
							ROLLBACK TRAN
							INSERT log_backup.dbo.backup_device
							(fecha,nombre,path,completo)
							VALUES
							(getdate(),'backup_'+@sysdatabases,@path,'No')
							/*Ejecuta el raise error que levanta el mensaje creado antes*/
							EXEC (@raiserror)							
							RETURN
		
						END
				END
			



/*
**Chequea si se realizo anteriormente algun backup de las bases del sistema 
** para hacer un backup full. Generalmente se ejecuta luego de la instalacion.
*/
	IF NOT EXISTS (
			SELECT backup_finish_date
			FROM msdb..backupset
			WHERE type='D'
			AND
			database_name=@sysdatabases
							)
		BEGIN
			/*Setea la variable con la sintaxis de un backup full*/
			SET @cmd_sysdb=('BACKUP DATABASE '+@sysdatabases + ' ' + 
			'TO backup_' + @sysdatabases + ' ' +		
			'WITH INIT, NAME="Backup inicial del dia '+
			CONVERT(VARCHAR(30),GETDATE())+'"'+
			',DESCRIPTION="Backup inicial"')

			
				EXEC  (@cmd_sysdb) --Ejecuta el backup


/*Inserta en la tabla SYSDB alguna modificacion*/		

			INSERT log_backup.dbo.sysdb
			(fecha,nombre,descripcion,completo)
			VALUES
			(getdate(),@sysdatabases,'Backup inical','Si')

			PRINT 'Actualizando tabla SYSDB' --Imprime mensaje OK

/*Chequea el estado de la variable @@error avortando en caso de error*/
					IF @@error<>0
						BEGIN
							PRINT 'Ha ocurrido un error desconocido al ejecutar backup bases del sistema'
							ROLLBACK TRAN
							INSERT log_backup.dbo.sysdb
							(fecha,nombre,descripcion,completo)
							VALUES
							(getdate(),@sysdatabases,'Backup inicial','No')
							/*Ejecuta el raise error que levanta el mensaje creado antes*/
							EXEC (@raiserror)
							RETURN
						END

				PRINT 'Primer Backup de la system database '+ @sysdatabases+ ' completado' --Imprime OK.

		END
ELSE




	SET @faltansysdb= (	SELECT TOP 1 CONVERT(SMALLDATETIME,GETDATE()) - CONVERT(SMALLDATETIME,backup_finish_date)   --Chequea si pasaron dos dias 
		FROM msdb.dbo.backupset		  --Desde el ultimo backup de cada base	
		WHERE database_name=@sysdatabases
		AND type='D'
		ORDER BY backup_finish_date DESC) 
/*
**Chequea la diferencia entre  el ultimo backup y la fecha actual. Si es mayor
**a tres dias, ejecuta el backup, sino sigue con el script.
**1900-01-01 00:00:00=ningun dia de diferencia
**1900-01-02 00:00:00=un dia de diferencia
**1900-01-03 00:00:00=dos dias de diferencia
**1900-01-04 00:00:00=tres dias de diferencia
*/
	IF @faltansysdb>CONVERT(SMALLDATETIME,'1900-01-04 00:00:00')
		BEGIN

					SET @cmd_sysdb=('BACKUP DATABASE '+@sysdatabases + ' ' + 
					'TO backup_' + @sysdatabases + ' ' +		
					'WITH INIT, NAME="Backup del dia '+
					CONVERT(VARCHAR(30),GETDATE())+'"'+
					',DESCRIPTION="Bases del Sistema cada 1 semana"')

								
						EXEC  (@cmd_sysdb)
			
			
/*Inserta en la tabla SYSDB alguna modificacion*/		
			BEGIN
			INSERT log_backup.dbo.sysdb
			(fecha,nombre,descripcion,completo)
			VALUES
			(getdate(),@sysdatabases,'Bases del Sistema cada 1 semana','Si')
			END	
			PRINT 'Actualizando tabla SYSDB'

/*Chequea el estado de la variable @@error avortando en caso de error*/
					IF @@error<>0
						BEGIN
							PRINT 'Ha ocurrido un error desconocido al ejecutar backup bases del sistema'
							ROLLBACK TRAN
							INSERT log_backup.dbo.sysdb
							(fecha,nombre,descripcion,completo)
							VALUES
							(getdate(),@sysdatabases,'Bases del Sistema cada 1 semana','No')
							/*Ejecuta el raise error que levanta el mensaje creado antes*/
							EXEC (@raiserror)
							RETURN
						END

				PRINT 'Backup Database '+ @sysdatabases+ ' completado' --Imprime OK.
				PRINT ' '

		END
/*
**Si todavia no hace falta hacer un backup
**Calcula cuanto tiempo hace falta y lo indica
*/

	ELSE
		IF
			@faltansysdb<CONVERT(SMALLDATETIME,'1900-01-02 00:00:00')
			BEGIN
			PRINT 'Falta un dia para hacer un backup de la base '+@sysdatabases
			PRINT ' '
			END
		ELSE
			BEGIN 
			PRINT 'Faltan de dos a tres dias para hacer un backup de la base '+@sysdatabases
			PRINT ' '
			END

	FETCH NEXT FROM sysdb_cursor INTO @sysdatabases						
END

/*Cierra los cursores abiertos*/
CLOSE sysdb_cursor
DEALLOCATE sysdb_cursor



/*
**Si la cantidad de errores durante la ejecucion del script es distinta de cero,
**realiza un rollback y lo indica. Si no imprime mensaje de finalizacion ok.
*/

	IF @@total_errors<>0
		BEGIN
			PRINT 'Ocurrio un error al finalizar la ejecucion total'
			ROLLBACK TRAN
			EXEC (@raiserror)
			RETURN

		END
	ELSE
		PRINT 'No se registraron errores en toda la ejecucion del script.'
		PRINT 'Dudas o consultas mandar un mail a racosta@iecisa.com.ar'
/*--------------------------------------------------------------------------------------------
**Fin de scripts. Dudas o consultas mandar un mail a racosta@iecisa.com.ar
----------------------------------------------------------------------------------------------*/

Rate

2 (1)

You rated this post out of 5. Change rating

Share

Share

Rate

2 (1)

You rated this post out of 5. Change rating