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)

Share

Share

Rate

2 (1)