madecapital.com
thefinancialtrading.com
grandesbodas.com
mundoface.com
goodtradings.com
good-trades.com
lasjugueterias.com
takenprofit.com
takesprofit.com
thetradingexperience.com
Escenario:
Múltiples sitios distribuidos, con varias bases de datos en cada uno de ellos.
Descripción:
El proceso de backup de base de datos esta compuesto por los módulos B1 y M1 que en su conjunto conforman un sistema modular para chequear la consistencia e integridad de las bases de datos MS SQL Server distribuidas, tanto de usuario como de sistema y su posterior backup, como así también, el monitoreo centralizado del mismo. Dichos módulos pueden correr en las versiones de MS SQL Server 7.0, 2000 y 2005.
Actualmente, este procedimiento modular está siendo utilizado en una instalación de 615 sitios remotos, con 14 bases de datos en cada uno con su respectivo control centralizado.
La siguiente figura describe el proceso global con sus respectivos módulos.

A continuación presentaremos los módulos B1 y M1 describiendo objetos y definiciones de cada uno de ellos.
Proceso de backup - modulo B1
El modulo B1, como citáramos en párrafos anteriores puede ejecutarse tanto en las versiones 7.0, 2000 y 2005 de MS SQL Server y consiste lógicamente en 2 Job’s denominados Job_Aux_DB1 y Job_Backup_DB1, que se ejecutan diariamente en forma nocturna en los sitios remotos.
La siguiente figura muestra como trabajan lógicamente ambos job’s.

A continuación realizaremos una descripción de los objetos y definiciones involucradas.
B1.Job’s
BEGIN TRANSACTION
DECLARE @JobID BINARY(16)
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF (SELECT COUNT(*) FROM msdb.dbo.syscategories WHERE name = N'[Uncategorized (Local)]') < 1
EXECUTE msdb.dbo.sp_add_category @name = N'[Uncategorized (Local)]'
IF (SELECT COUNT(*) FROM msdb.dbo.sysjobs WHERE name = N'Backup Diario Aux DB1') > 0
PRINT N'The job "Backup Diario Aux DB1" already exists so will not be replaced.'
ELSE
BEGIN
-- Add the job
EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT , @job_name = N'Backup Diario Aux DB1', @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
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the job steps
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = N'CHEQUEO', @command = N'D:\mssql\Backup\DB1\ChkDB1.bat', @database_name = N'', @server = N'', @database_user_name = N'', @subsystem = N'CmdExec', @cmdexec_success_code = 0, @flags = 0, @retry_attempts = 0, @retry_interval = 1, @output_file_name = N'D:\mssql\Backup\DB1\ChequeoStartJOBBat', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the job schedules
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id = @JobID, @name = N'Schedule AUX DB1', @enabled = 1, @freq_type = 4, @active_start_date = 19900101, @active_start_time = 220000, @freq_interval = 1, @freq_subday_type = 1, @freq_subday_interval = 0, @freq_relative_interval = 0, @freq_recurrence_factor = 0, @active_end_date = 99991231, @active_end_time = 235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the Target Servers
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
--***********************
BEGIN TRANSACTION
DECLARE @JobID BINARY(16)
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF (SELECT COUNT(*) FROM msdb.dbo.syscategories WHERE name = N'[Uncategorized (Local)]') < 1
EXECUTE msdb.dbo.sp_add_category @name = N'[Uncategorized (Local)]'
IF (SELECT COUNT(*) FROM msdb.dbo.sysjobs WHERE name = N'Backup diario DB1') > 0
PRINT N'The job "Backup diario DB1" already exists so will not be replaced.'
ELSE
BEGIN
-- Add the job
EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT , @job_name = N'Backup diario DB1', @owner_login_name = N'sa', @description = N'Backup diario DB1', @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
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the job steps
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = N'Backup DATA DB1', @command = N'BACKUP DATABASE DB1 TO DB1_backup WITH INIT if (@@error != 0) RAISERROR (''No se pudo efectuar backup de DB1'',20,127) WITH LOG
', @database_name = N'master', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 0, @retry_attempts = 0, @retry_interval = 5, @output_file_name = N'D:\Mssql\Backup\DB1\ChequeoStartJOB', @on_success_step_id = 2, @on_success_action = 4, @on_fail_step_id = 0, @on_fail_action = 2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 2, @step_name = N'Backup LOG DB1', @command = N'BACKUP LOG DB1 TO DB1LOG_backup WITH INIT if (@@error != 0) RAISERROR (''No se pudo efectuar backup de LOG de DB1'',20,127) WITH LOG
', @database_name = N'master', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 2, @retry_attempts = 0, @retry_interval = 1, @output_file_name = N'D:\Mssql\Backup\DB1\ChequeoStartJOB', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the Target Servers
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
B1.Batchs de SO
1) ChkDB1.bat
ECHO OFF
set WorkDirectory=D:\MSSql\Backup\Attrs\
del %WorkDirectory%dbccDB1.*
ECHO ******************************************************* > %WorkDirectory%dbccDB1.out
ECHO Chequeo de DB1 del servidor %COMPUTERNAME% >> %WorkDirectory%dbccDB1.out
ECHO ******************************************************* >> %WorkDirectory%dbccDB1.out
osql -E -i%WorkDirectory%dbcDB1.sql -n -h-1 >> %WorkDirectory%dbccDB1.out
findstr /i /g:%WorkDirectory%search.txt %WorkDirectory%dbccDB1.out > %WorkDirectory%dbccDB1.err
osql -E -i%WorkDirectory%bcpStart.sql > %WorkDirectory%bcpstart.out
B1.Scripts SQL Server
1) DbcDB1.sql
use DB1
go
set nocount on
if (@@error != 0) RAISERROR ("No se pudo abrir ,DB1",20,127) WITH LOG
select ''
select ''
select 'Chequeo de DB1!!'
go
set nocount on
DBCC CHECKDB
DBCC NEWALLOC
DBCC CHECKCATALOG
2) BCPSTART.sql
use tempdb
go
CREATE TABLE DbccOut(Linea varchar(255))
exec master..xp_cmdshell "bcp tempdb..DbccOut in D:\MSSql\Backup\attrs\dbccDB1.err -c -T"
declare @cErrores int
select @cErrores = count(*) from DbccOut
drop table DbccOut
if (@cErrores != 0)
RAISERROR ("Existe un error en la base DB1!!",20,127) WITH LOG
else
exec msdb..sp_start_job @job_name = 'Backup Diario DB1'
B1.Archivo con patrones de búsqueda de errores:
1) search.txt
table corrupt
level 16
level 17
level 18
level 19
level 20
level 21
severity: 16
severity: 17
severity: 18
severity: 19
severity: 20
severity: 21
severity: 22
severity: 23
severity: 24
severity: 25
B1.T-SQL de los Jobs SQL Server
1)
BACKUP DATABASE DB1 TO DB1_backup WITH INIT if (@@error != 0) RAISERROR ('No se pudo efectuar backup de DB1',20,127) WITH LOG
BACKUP LOG DB1 TO DB1LOG_backup WITH INIT if (@@error != 0) RAISERROR ('No se pudo efectuar backup de LOG de DB1',20,127) WITH LOG
2)
BACKUP LOG DB1 TO DB1LOG_backup
Citados los objetos involucrados en el procedimiento, a continuación vamos a realizar una descripción del comportamiento de los mismos.
El Job Job_Aux_DB ejecuta un script de SO llamado ChkDB1.bat, donde DB1 es el nombre de la base de datos a realizar el chequeo y posterior backup.
Este Batch realiza las siguientes tareas:
Se eliminan todos los archivos de salida de ejecuciones anteriores.
Se ejecuta un script SQL llamado dbcDB1.sql, que realizará todas las ejecuciones de los DBCC para chequear consistencia de la base de datos DB1, generando un archivo con el reporte de la ejecución de los mismos denominado dbccDB1.out.
Posteriormente se ejecuta un findstr.exe (findstring) que buscará determinados patrones de error,indicados en search.txt, dentro de dicho reporte de salida de los DBCCs., y dejando en el archivo dbccDB1.err si es que se encontró alguno de los errores tipificados.
Luego se ejecuta un osql donde se carga en la base de datos TempDB, la tabla temporal DbccOut, con el arhivo de los errores encontrados. A continuación se cuenta la cantidad de registros de dicha tabla temporal, y si existen registros –lo cual implicaría que hubo errores en algún DBCC ejecutado- se escribe en el log que existen errores en la base de datos en cuestión y se termina el procedimiento. Por el contrario, ante la inexistencia de registros en la tabla temporal, se dispara el segundo job SQL Server denominado Job_Backup_DB.
El Job Job_Backup_DB consta de dos pasos de tipo Transact SQL.
En el primero se realiza el backup de la base de datos a un dispositivo de backup, inicializándolo. Si este paso finaliza exitosamente, se pasa el control al próximo paso, de lo contrario se escribe en el log el error ocurrido y se aborta la ejecución del job completo.
El segundo paso ejecuta el backup del log de la base de datos en cuestión, a otro dispositivo de backup generado para esta finalidad, inicializándolo.
Adicionalmente, durante todo el día, con la frecuencia que se determine según el nivel de utilización de cada base de datos, se ejecuta otro job SQL Server que realiza el backup transaccional de la base de datos resguardándolo en el dispositivo de backup de log, sin sobrescribirlo, es decir haciendo append, de manera que hasta tanto se tome un backup completo de la base de datos, se cuenta con el backup full de la base de datos anterior y todos los backups del log de la misma, pudiéndose realizar recovery de la misma hasta el momento que sea necesario.
Este dispositivo se inicializa en el proceso nocturno, cuando ya se cuenta con un nuevo backup de la base de datos.
Proceso de monitoreo - modulo M1
El modulo M1, puede ejecutarse en el entorno de las versiones 7.0, 2000 y 2005 de MS SQL Server y consiste en la definición de una Base de Datos, un Job de SQL Server, tres stored procedures, el primero de consulta distribuida, el segundo para consulta en tabla de resultados y reportar errores mediante un raiserror y el tercero para la consulta propiamente dicha de los sitios con errores varios, por otro lado, la generación y definición de tres tablas, una para almacenar resultados diarios, otra para almacenar resultado históricos y la última tabla para obtener nombre del DBMS y descripción de la misma, la definición de una alerta, operadores varios y sus estaciones de trabajo para poder lanzar la alarma a cada uno y para finalizar un script SQL donde se realiza la consulta a tablas de sistema de los sitios distribuidos.
Este proceso se ejecuta centralizado para controlar los job’s definidos en los sitios remotos.
La siguiente figura muestra como trabajan en forma lógica el job y todos los objetos asociados.

A continuación realizaremos una descripción de los objetos y definiciones involucradas.
Objetos Modulo M1:
M1.Base de Datos
Nombre: BM11
M1.Tablas
CREATE TABLE [dbo].[SucursalesProd_bis] (
[Server] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AI NOT NULL ,
[Sucursal] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[TBL_Desc_Sucur] (
[Sucursal] [varchar] (12) COLLATE SQL_Latin1_General_CP1_CI_AI NULL ,
[Descripcion] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AI NULL ,
[DiaHora] [datetime] NULL ,
[Script] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AI NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[TBL_Desc_Sucur_Hist] (
[Sucursal] [varchar] (12) COLLATE SQL_Latin1_General_CP1_CI_AI NULL ,
[Descripcion] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AI NULL ,
[DiaHora] [datetime] NULL ,
[Script] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AI NULL
) ON [PRIMARY]
GO
M1.Stored Procedures
1) Err_Backup_Prod
CREATE PROCEDURE [Err_Backup_Prod] AS
IF((SELECT COUNT(*) FROM tbl_desc_sucur
WHERE descripcion <> '1> 2> 1> 2> 3> 4> 5> 6> 7> 8> 9> 10> 11> 12>' and
descripcion <> '1> 2> 1> 2> 3> 4> 5> 6> 7> 8> 9> 10> 11> 12> 13>' and
descripcion <> '1> 2> 1> 2> 3> 4> 5> 6> 7> 8> ' ) >=1)
RAISERROR (50001,16,1) WITH LOG
GO
2) Consulta_Err_Backup
CREATE PROCEDURE [Consulta_Err_Backup] AS
SELECT * FROM tbl_desc_sucur
WHERE descripcion <> '1> 2> 1> 2> 3> 4> 5> 6> 7> 8> 9> 10> 11> 12>' and
descripcion <> '1> 2> 1> 2> 3> 4> 5> 6> 7> 8> 9> 10> 11> 12> 13>' and
descripcion <> '1> 2> 1> 2> 3> 4> 5> 6> 7> 8> '
GO
3) SenMasiva
CREATE PROCEDURE Sen_Masiva
@sentencia varchar(255),
@script varchar(255)
WITH ENCRYPTION
AS
CREATE TABLE #T(ERR VARCHAR(255))
DECLARE @server varchar(20)
DECLARE @sentfinal varchar(255)
DECLARE @salida varchar(255)
--cursor
DECLARE NroSucursal_cursor CURSOR
FOR SELECT Server FROM SucursalesProd_bis
OPEN NroSucursal_cursor
FETCH NEXT FROM NroSucursal_cursor into @server
WHILE @@fetch_status = 0
BEGIN
BEGIN TRAN
SET @sentfinal= @sentencia +' '+'-S'+@server+' '+'-h-1'+' '+'-UBM11'+'-Pbm'+' '+'-t15000'
INSERT INTO #T EXEC master..xp_cmdshell @sentfinal
SET @salida = (SELECT TOP 1 * FROM #T)
INSERT TBL_Desc_Sucur VALUES (@server,@salida,GETDATE(),@script)
DELETE #T
IF @@ERROR = 0
COMMIT TRAN
FETCH NEXT FROM NroSucursal_cursor into @server
END
close NroSucursal_cursor
deallocate NroSucursal_cursor
drop table #T
GO
M1.Mensaje
sp_addmessage 50001,21,"Problemas en backup's distribuidos",'english',TRUE
M1.Operadores
EXECUTE msdb.dbo.sp_add_operator @name = N'Pepe', @enabled = 1, @netsend_address = N'P4I028TPYWTF1HV', @category_name = N'[Uncategorized]', @weekday_pager_start_time = 80000, @weekday_pager_end_time = 180000, @saturday_pager_start_time = 80000, @saturday_pager_end_time = 180000, @sunday_pager_start_time = 80000, @sunday_pager_end_time = 180000, @pager_days = 62
EXECUTE msdb.dbo.sp_add_notification @alert_name = N' Error Backup Distribuidos', @operator_name = N'Pepe', @notification_method = 1
M1.Alerta
EXECUTE msdb.dbo.sp_add_alert @name = N'Error Backup Distribuidos', @message_id = 50001, @severity = 0, @enabled = 1, @delay_between_responses = 60, @include_event_description_in = 4, @database_name = N'BM11', @category_name = N'[Uncategorized]'
EXECUTE msdb.dbo.sp_add_notification @alert_name = N'Error Backup Distribuidos', @operator_name = N'Pepe', @notification_method = 1
M1.Script SQL
FailedBackupsJobsCFecha.SQL
USE msdb
go
DECLARE @parfecha char(8)
SELECT @parfecha=convert(char,dateadd(day,-1,getdate()),112)
SELECT TOP 1 message
FROM sysjobhistory
WHERE (step_name = 'chequeo' or step_name like 'Backup %') and (run_status = 0
and run_date >=@parfecha)
M1.Job SQL Server
BEGIN TRANSACTION
DECLARE @JobID BINARY(16)
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
IF (SELECT COUNT(*) FROM msdb.dbo.syscategories WHERE name = N'Database Maintenance') < 1
EXECUTE msdb.dbo.sp_add_category @name = N'Database Maintenance'
IF (SELECT COUNT(*) FROM msdb.dbo.sysjobs WHERE name = N'Chequeo_Backup_Distribuidos') > 0
PRINT N'The job "Chequeo_Backup_Distribuidos" already exists so will not be replaced.'
ELSE
BEGIN
-- Add the job
EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT , @job_name = N'Chequeo_Backup_Distribuidos', @owner_login_name = N'sa', @description = N'No description available.', @category_name = N'Database Maintenance', @enabled = 1, @notify_level_email = 0, @notify_level_page = 0, @notify_level_netsend = 0, @notify_level_eventlog = 2, @delete_level= 0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the job steps
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 1, @step_name = N'Chequeo', @command = N'INSERT INTO tbl_desc_sucur_hist SELECT * FROM tbl_desc_sucur
DELETE tbl_desc_sucur
EXEC Sen_Masiva ''osql -iD:\MSSQL\FailedBackupsJobsCFecha.SQL'', ''FailedBackupsJobsCFecha.SQL''
', @database_name = N'BM11', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 0, @retry_attempts = 0, @retry_interval = 1, @output_file_name = N'', @on_success_step_id = 2, @on_success_action = 4, @on_fail_step_id = 0, @on_fail_action = 2
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID, @step_id = 2, @step_name = N'Notificacion', @command = N'EXEC Err_Backup_Prod', @database_name = N'BM11', @server = N'', @database_user_name = N'', @subsystem = N'TSQL', @cmdexec_success_code = 0, @flags = 0, @retry_attempts = 0, @retry_interval = 1, @output_file_name = N'', @on_success_step_id = 0, @on_success_action = 1, @on_fail_step_id = 0, @on_fail_action = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the job schedules
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id = @JobID, @name = N'Schedule Chequeo Backup Distribuidos', @enabled = 1, @freq_type = 8, @active_start_date = 19900101, @active_start_time = 23300, @freq_interval = 127, @freq_subday_type = 1, @freq_subday_interval = 0, @freq_relative_interval = 0, @freq_recurrence_factor = 1, @active_end_date = 99991231, @active_end_time = 235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
-- Add the Target Servers
EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
Citados los objetos involucrados en el procedimiento, a continuación vamos a realizar una descripción del comportamiento de los mismos.
El Job Chequea_Sitios tiene definidos dos pasos, Chequeo y Notificación.
El paso Chequeo posee definidos tres tareas del tipo Transact-SQL, la primer tarea es realizar una operación de select - insert para copiar datos diarios de la tabla tbl_desc_sucur a la tabla histórica tbl_desc_sucur_hist, la segunda borra los datos de la tabla tbl_desc_sucur y la tercera ejecuta el stored procedure SenMasiva. Este stored procedure carga un cursor llamado Server_cursor obteniendo los registros de la tabla sucursalesprod_bis para obtener el nombre del DBMS SQLServer de cada sitio remoto y de esta manera armar la sentencia de chequeo definitiva y ejecutarla en cada sitio; el resultado de la operación serializada, se graba en la tabla tbl_desc_sucur. Una vez finalizado el chequeo sitio por sitio continua con el siguiente paso.
El paso Notificación ejecuta el stored procedure Err_Backup_Prod el cual realiza una consulta de cantidad de registros que no cumplan con diversas condiciones (‘1> 2> 1> 2> 3> 4> 5> 6> 7> 8> 9> 10> 11> 12> 13>’, ’1> 2> 1> 2> 3> 4> 5> 6> 7> 8> 9> 10> 11> 12>’,’1> 2> 1> 2> 3> 4> 5> 6> 7> 8>’) en el campo descripción de la tabla tbl_desc_sucur, si el resultado es > = 1 entonces lanza un RAISEERROR con el ID 50001, el mensaje ‘Problemas en backup's distribuidos‘ y luego se lanza una alerta que es notificada mediante y en este caso con net send a cada operador definido. Posteriormente el operador ejecuta el stored procedure Consulta_Err_Backup, el cual devuelve un conjunto de registros con el nombre del DBMS SQLServer y los mensajes de error recolectados. Si la cantidad de registros que no cumplen la condicion es = 0 el proceso finaliza.
En la siguiente figura muestra el procedimiento detallado en párrafos anteriores.

Para finalizar, destacamos la ventaja de poder implementar estos módulos en forma independiente dependiendo de la criticidad, tiempo de recovery y cantidad de sitios a implementar. Cabe señalar que el módulo M1 puede ser utilizado también para el control de otros jobs SQL Server y para disparar la ejecución de scripts contra los sitios remotos.
Y como siempre, Abrazo virtual para todos!!!!,
JuanPL