sql >> Base de Datos >  >> RDS >> Sqlserver

Configuración de notificaciones de correo de base de datos en MS SQL Server

Introducción

A menudo, existe la necesidad de informar de alguna manera a los administradores sobre los problemas con un servidor. Las notificaciones generalmente se dividen en 2 tipos:

1) notificaciones en tiempo real, es decir, aquellas que deben llegar inmediatamente cuando ocurre un problema

2) notificaciones retrasadas, es decir, aquellas que llegan después de un tiempo bastante largo (más de 1 hora) después de que ocurre un problema.

En mi trabajo, era necesario ampliar la funcionalidad del correo de base de datos de SQL Server normal.

En este artículo, consideraremos un ejemplo de cómo generar notificaciones en tablas HTML y luego enviarlas a los administradores.

Solución

1. Configurar correo electrónico de base de datos

2. Crear una tabla para destinatarios:

[expandir título =”Código”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Recipient]( [Recipient_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL, [Recipient_Name] [nvarchar](255) NOT NULL, // un correo electrónico principal del destinatario [ Recipient_Code] [nvarchar](10) NOT NULL, // código del destinatario [IsDeleted] [bit] NOT NULL, // un indicador de eliminación (si se usa un destinatario o no) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Recipient ] CLAVE PRIMARIA AGRUPALADA ( [GUID_destinatario] ASC) CON (PAD_INDEX =DESACTIVADO, ESTADÍSTICAS_NORECOMPUTE =DESACTIVADO, IGNORE_DUP_KEY =DESACTIVADO, ALLOW_ROW_LOCKS =ACTIVADO, ALLOW_PAGE_LOCKS =ACTIVADO) ACTIVADO [PRIMARIO], RESTRICCIÓN [AK_Recipient_Code] ÚNICO NO AGLUSTRADO ( [Recipient_Code] ASC) CON (PAD_INDEX =DESACTIVADO, ESTADÍSTICAS_NORECOMPUTE =DESACTIVADO, IGNORE_DUP_KEY =DESACTIVADO, ALLOW_ROW_LOCKS =ACTIVADO, ALLOW_PAGE_LOCKS =ACTIVADO) ACTIVADO [PRIMARIO], RESTRICCIÓN [AK_Recipient_Name] ÚNICO NO CLÚSCULO ([Recipient_Name] ASC) CON (PAD_INDEX =DESACTIVADO, ESTADÍSTICAS_NORECOMPUTE =OF F, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]GOALTER TABLE [srv].[Recipient] ADD CONSTRAINT [DF_Recipient_Recipient_GUID] DEFAULT (nuevoidsecuencial()) PARA [Recipient_GUID]GOALTER TABLE [ srv].[Destinatario] ADD CONSTRAINT [DF_Recipient_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]GOALTER TABLE [srv].[Recipient] ADD CONSTRAINT [DF_Recipient_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]GO

[/expandir]

3. Cree una tabla para las direcciones de los destinatarios:

[expandir título =”Código”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Address]( [Address_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL, [Recipient_GUID] [uniqueidentifier] NOT NULL, // destinatario [Dirección] [nvarchar]( 255) NOT NULL, // correo electrónico [IsDeleted] [bit] NOT NULL, // indicador de eliminación (si el correo electrónico se usa o no) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED ([Address_GUID] ASC )CON (PAD_INDEX =DESACTIVADO, ESTADÍSTICAS_NORECOMPUTE =DESACTIVADO, IGNORE_DUP_KEY =DESACTIVADO, ALLOW_ROW_LOCKS =ACTIVADO, ALLOW_PAGE_LOCKS =ACTIVADO) ACTIVADO [PRIMARIO], RESTRICCIÓN [AK_Address] ÚNICO NO CLÚSCULO ([Recipient_GUID] ASC, [Dirección] ASC) CON (PAD_INDEX =DESACTIVADO) , STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]GOALTER TABLE [srv].[Address] ADD CONSTRAINT [DF_Address_Address_GUID] DEFAULT (nuevoidsecuencial()) PARA [Address_GUID] MESA DE PORTERO [ srv].[Dirección] ADD CONSTRAINT [DF_Address_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]GOALTER TABLE [srv].[Address] ADD CONSTRAINT [DF_Address_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]GO

[/expandir]

4. Cree una tabla para una cola de mensajes:

[expandir título =”Código”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfo]( [ErrorInfo_GUID] [identificador único] NOT NULL, [ERROR_TITLE] [nvarchar](max) NULL, // título [ERROR_PRED_MESSAGE] [nvarchar] (max) NULL, // información preliminar [ERROR_NUMBER] [nvarchar](max) NULL, // mensaje (error) código [ERROR_MESSAGE] [nvarchar](max) NULL, // mensaje [ERROR_LINE] [nvarchar](max) NULL, // número de línea [ERROR_PROCEDURE] [nvarchar](max) NULL, // procedimiento almacenado [ERROR_POST_MESSAGE] [nvarchar](max) NULL, // información explicativa [RECIPIENTS] [nvarchar](max) NULL, // destinatarios separados por ';' [InsertDate] [datetime] NOT NULL, [StartDate] [datetime] NOT NULL, // fecha y hora de inicio [FinishDate] [datetime] NOT NULL, // fecha y hora de finalización [Count] [int] NOT NULL, // número de veces [UpdateDate] [dat etime] NOT NULL, [IsRealTime] [bit] NOT NULL, // indicador en tiempo real [InsertUTCDate] [datetime] NULL, CONSTRAINT [PK_ErrorInfo] PRIMARY KEY CLUSTERED ([ErrorInfo_GUID] ASC)WITH (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_ErrorInfo_GUID] DEFAULT (newid()) FOR [ErrorInfo_GUID]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_InsertDate] DEFAULT (getdate()) FOR [InsertDate]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_StartDate] DEFAULT (getdate()) FOR [StartDate]GOALTER TABLE [ srv].[ErrorInfo] AGREGAR RESTRICCIÓN [DF_ErrorInfo_FinishDate] PREDETERMINADO (getdate()) PARA [FinishDate]GOALTER TABLE [srv].[ErrorInfo] AGREGAR RESTRICCIÓN [DF_ErrorInfo_Count] DEFAULT ((1)) PARA [Count]GOALTER TABLE [srv] .[ErrorInfo] AGREGAR RESTRICCIÓN [DF__ErrorInfo__Updat__5FFEE747] DEFAU LT (getdate()) FOR [UpdateDate]GOALTER TABLE [srv].[ErrorInfo] AGREGAR RESTRICCIÓN [DF_ErrorInfo_IsRealTime] PREDETERMINADO ((0)) FOR [IsRealTime]GOALTER TABLE [srv].[ErrorInfo] AGREGAR RESTRICCIÓN [DF_ErrorInfo_InsertUTCDate] DEFAULT ( getutcdate()) PARA [InsertUTCDate]IR

[/expandir]

5. Cree una tabla de archivo para los mensajes enviados desde la cola de mensajes:

[expandir título =”Código”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfoArchive]( [ErrorInfo_GUID] [identificador único] ROWGUIDCOL NOT NULL, [ERROR_TITLE] [nvarchar](max) NULL, [ERROR_PRED_MESSAGE] [nvarchar](max ) NULL, [ERROR_NUMBER] [nvarchar](max) NULL, [ERROR_MESSAGE] [nvarchar](max) NULL, [ERROR_LINE] [nvarchar](max) NULL, [ERROR_PROCEDURE] [nvarchar](max) NULL, [ERROR_POST_MESSAGE] [nvarchar](max) NULL, [RECIPIENTS] [nvarchar](max) NULL, [InsertDate] [datetime] NOT NULL, [StartDate] [datetime] NOT NULL, [FinishDate] [datetime] NOT NULL, [Count] [ int] NOT NULL, [UpdateDate] [datetime] NOT NULL, [IsRealTime] [bit] NOT NULL, [InsertUTCDate] [datetime] NULL, RESTRICCIÓN [PK_ArchiveErrorInfo] PRIMARY KEY CLUSTERED ([ErrorInfo_GUID] ASC)WITH (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =DESACTIVADO, IGNORE_DUP_KEY =DESACTIVADO, ALLOW_ROW_LOCKS =ACTIVADO, ALLOW_PAGE_LOCKS =ACTIVADO) ON [PRIMARIO]) ON [PRIMARIO] TEXTIMAGE_ON [PRIMARIO]GOALTE R TABLE [srv].[ErrorInfoArchive] AGREGAR RESTRICCIÓN [DF_ErrorInfoArchive_ErrorInfo_GUID] PREDETERMINADO (nuevoidsecuencial()) PARA [ErrorInfo_GUID] TABLA DE OBJETIVO [srv]. [ErrorInfoArchive] AGREGAR RESTRICCIÓN [DF_ArchiveErrorInfo_InsertDate] PREDETERMINADO (getdate()) PARA [InsertDate] TABLA DE OBJETIVO [srv].[ErrorInfoArchive] AGREGAR RESTRICCIÓN [DF_ErrorInfoArchive_StartDate] PREDETERMINADO (getdate()) PARA [StartDate]GOALTER TABLE [srv].[ErrorInfoArchive] AGREGAR RESTRICCIÓN [DF_ErrorInfoArchive_FinishDate] PREDETERMINADO (getdate()) PARA [FinishDate]GOALTER TABLE [srv] ].[ErrorInfoArchive] AGREGAR RESTRICCIÓN [DF_ErrorInfoArchive_Count] DEFAULT ((1)) PARA [Count]GOALTER TABLE [srv].[ErrorInfoArchive] AGREGAR RESTRICCIÓN [DF_ErrorInfoArchive_UpdateDate] DEFAULT (getdate()) FOR [UpdateDate]GOALTER TABLE [srv]. [ErrorInfoArchive] AGREGAR RESTRICCIÓN [DF_ErrorInfoArchive_IsRealTime] PREDETERMINADO ((0)) PARA [IsRealTime]GOALTER TABLE [srv].[ErrorInfoArchive] AGREGAR RESTRICCIÓN [DF_ErrorInfoArchive_InsertUTCDate] PREDETERMINADO (getutcdate()) PARA [InsertUTCDate]GO

[/expandir]

Esta información es necesaria para el historial. Además, esta tabla debe borrarse de los datos muy antiguos (por ejemplo, más de un mes).

6. Cree un procedimiento almacenado que registre un nuevo mensaje en la cola de mensajes:

[expandir título =”Código”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[ErrorInfoIncUpd] @ERROR_TITLE nvarchar(max), @ERROR_PRED_MESSAGE nvarchar(max), @ERROR_NUMBER nvarchar(max), @ERROR_MESSAGE nvarchar(max), @ERROR_LINE nvarchar(max), @ERROR_PROCEDURE nvarchar(max), @ERROR_POST_MESSAGE nvarchar(max), @RECIPIENTS nvarchar(max), @StartDate datetime=null, @FinishDate datetime=null, @IsRealTime bit =0ASBEGIN /* Error al iniciar sesión en el error tabla que se enviará por correo electrónico si la tabla ya tiene una entrada con el mismo título, contenido y remitente, la fecha de finalización del error, la fecha de actualización del registro, así como la cantidad de errores cambiará */ SET NOCOUNT SOBRE; declarar @ErrorInfo_GUID identificador único; seleccione top 1 @ErrorInfo_GUID=ErrorInfo_GUID de srv.ErrorInfo donde ([email protected]_TITLE o @ERROR_TITLE es nulo) y [email protected] y ([email protected]_MESSAGE o @ERROR_MESSAGE es nulo) y ([email protected]_PRED_MESSAGE o @ERROR_PRED_MESSAGE es nulo) y ([email protected]_POST_MESSAGE o @ERROR_POST_MESSAGE es nulo) y ([email protected] o @IsRealTime es nulo); if(@ErrorInfo_GUID is null) begin insert into srv.ErrorInfo ( ERROR_TITLE ,ERROR_PRED_MESSAGE ,ERROR_NUMBER ,ERROR_MESSAGE ,ERROR_LINE ,ERROR_PROCEDURE ,ERROR_POST_MESSAGE ,RECIPIENTS ,IsRealTime ,StartDate ,FinishDate ) select @ERROR_TITLE ,@ERROR_PRED_MESSAGE ,@ERROR_NUMBER ,@ERROR_MESSAGE ,@ ERROR_LINE ,@ERROR_PROCEDURE ,@ERROR_POST_MESSAGE ,@RECIPIENTS ,@IsRealTime ,isnull(@StartDate, getdate()) ,isnull(@FinishDate,getdate()) end else begin update srv.ErrorInfo set FinishDate=getdate(), [Count]=[Count]+1, UpdateDate=getdate() where [email protected]_GUID; finENDGO

[/expandir]

7. Cree un procedimiento almacenado que devuelva una cadena de las direcciones por código o la dirección de correo electrónico principal de un destinatario:

[expandir título =”Código”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetRecipients]@Recipient_Name nvarchar(255)=NULL,@Recipient_Code nvarchar(10)=NULL,@Recipients nvarchar(max) out/* El procedimiento para creación de notificaciones por correo electrónico*/ASBEGIN SET NOCOUNT ON; establecer @Destinatarios=''; seleccione @[email protected]+d.[Dirección]+';' from srv.Recipient as r inner join srv.[Address] as d on r.Recipient_GUID=d.Recipient_GUID where ([email protected]_Name or @Recipient_Name IS NULL) and ([email protected]_Code or @Recipient_Code IS NULL) y r.IsDeleted=0 y d.IsDeleted=0; --ordenar por r.InsertUTCDate desc, d.InsertUTCDate desc; if(len(@Recipients)>0) set @Recipients=substring(@Recipients,1,len(@Recipients)-1);ENDGO

[/expandir]

8. Cree las funciones necesarias para trabajar con fechas y horas:

[expandir título =”Código”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [rep].[GetDateFormat] ( @dt datetime, // fecha de entrada @format int=0 // formato preestablecido)RETURNS nvarchar(255)AS/* Devuelve la fecha como una cadena según el formato especificado y la fecha de entrada Inserta ceros donde sea necesario:formato entrada fecha resultado 0 17.4.2014 "17.04.2014" 1 17.4.2014 "04.2014" 1 8.11.2014 "11.2014" 2 17.04.2014 "2014" */COMENZAR DECLARAR @res nvarchar(255); DECLARAR @día int=DÍA(@dt); DECLARAR @mes int=MES(@dt); DECLARAR @año int=AÑO(@dt); if(@format=0) begin set @res=IIF(@day<10,'0'+cast(@day as nvarchar(1)), cast(@day as nvarchar(2)))+'.'; set @[email protected]+IIF(@month<10,'0'+cast(@month as nvarchar(1)), cast(@month as nvarchar(2)))+'.'; establecer @[email protected]+cast(@year as nvarchar(255)); end else if(@format=1) begin set @res=IIF(@month<10,'0'+cast(@month as nvarchar(1)), cast(@month as nvarchar(2)))+'. '; establecer @[email protected]+cast(@year as nvarchar(255)); end else if(@format=2) begin set @res=cast(@year as nvarchar(255)); end RETURN @res;ENDGOUSE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [rep].[GetTimeFormat] ( @dt datetime, // hora de entrada @format int=0 // formato preestablecido)RETURNS nvarchar(255)AS/* Devuelve hora como una cadena de acuerdo con el formato especificado y la hora de entrada Inserta ceros donde sea necesario:formato de hora de entrada resultado 0 17:04 "17:04:00" 1 17:04 "17:04" 1 8:04 "08:04 " 2 17:04 "17"*/COMIENZO DECLARAR @res nvarchar(255); DECLARAR @hora int=DATEPART(HORA, @dt); DECLARAR @min int=DATEPART(MINUTE, @dt); DECLARAR @sec int=DATEPART(SEGUNDO, @dt); if(@format=0) begin set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2)))+':'; establecer @[email protected]+IIF(@min<10,'0'+cast(@min as nvarchar(1)), cast(@min as nvarchar(2)))+':'; establecer @[email protected]+IIF(@sec<10,'0'+cast(@sec as nvarchar(1)), cast(@sec as nvarchar(2))); end else if(@format=1) begin set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2)))+':'; establecer @[email protected]+IIF(@min<10,'0'+cast(@min como nvarchar(1)), cast(@min como nvarchar(2))); end else if(@format=2) begin set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2))); fin RETORNO @res;ENDGO

[/expandir]

9. Cree un procedimiento almacenado que genere un informe HTML sobre los mensajes en forma de tabla:

[expandir título =”Código”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetHTMLTable] @recipients nvarchar(max),@dt datetime // en qué fecha leer ASBEGIN /* genera código HTML para la tabla */ SET NOCOUNT ON; declarar @body nvarchar(max); declare @tbl table(ID int identidad(1,1) ,[ERROR_TITLE] nvarchar(max) ,[ERROR_PRED_MESSAGE] nvarchar(max) ,[ERROR_NUMBER] nvarchar(max) ,[ERROR_MESSAGE] nvarchar(max) ,[ERROR_LINE] nvarchar (max) ,[ERROR_PROCEDURE] nvarchar(max) ,[ERROR_POST_MESSAGE] nvarchar(max) ,[InsertDate] datetime ,[StartDate] datetime ,[FinishDate] datetime ,[Count] int ); declarar @ID int ,@ERROR_TITLE nvarchar(max) ,@ERROR_PRED_MESSAGE nvarchar(max) ,@ERROR_NUMBER nvarchar(max) ,@ERROR_MESSAGE nvarchar(max) ,@ERROR_LINE nvarchar(max) ,@ERROR_PROCEDURE nvarchar(max) ,@ERROR_POST_MESSAGE nvarchar (máx.), @InsertDate datetime, @StartDate datetime, @FinishDate datetime, @Count int insert into @tbl( [ERROR_TITLE],[ERROR_PRED_MESSAGE],[ERROR_NUMBER],[ERROR_MESSAGE],[ERROR_LINE],[ERROR_PROCEDURE],[ERROR_POST_MESSAGE ] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] ) seleccione los 100 principales [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[MENSAJE_ERROR] ,[LINEA_ERROR] ,[PROCEDIMIENTO_ERROR] ,[MENSAJE_POST_ERROR] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] from [srv].[ErrorInfo] where ([RECIPIENTS][email protected] ) o (@recipients IS NULL) e InsertDate'; establecer @[email protected]+''; establecer @[email protected]+'№ п/п'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'FECHA'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'ERROR'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'DESCRIPCIÓN'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'CÓDIGO DE ERROR'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'MENSAJE'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'INICIO'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'FINALIZAR'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'NÚMERO'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'NÚMERO DE LÍNEA'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'PROCEDIMIENTO'; establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+'NOTA'; establecer @[email protected]+''; establecer @[email protected]+''; while((select top 1 1 from @tbl)>0) begin set @[email protected]+''; seleccionar top 1 @ID =[ID] ,@ERROR_TITLE =[ERROR_TITLE] ,@ERROR_PRED_MESSAGE=[ERROR_PRED_MESSAGE] ,@ERROR_NUMBER =[ERROR_NUMBER] ,@ERROR_MESSAGE =[ERROR_MESSAGE] ,@ERROR_LINE =[ERROR_LINE] ,@ERROR_PROCEDURE =[ERROR_PROCEDURE ] ,@ERROR_POST_MESSAGE=[ERROR_POST_MESSAGE] ,@InsertDate =[InsertDate] ,@StartDate =[StartDate] ,@FinishDate =[FinishDate] ,@Count =[Count] from @tbl order by InsertDate asc; establecer @[email protected]+''; establecer @[email protected]+cast(@ID as nvarchar(max)); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+rep.GetDateFormat(@InsertDate, predeterminado)+' '+rep.GetTimeFormat(@InsertDate, predeterminado); // cast(@InsertDate as nvarchar(max)); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+isnull(@ERROR_TITLE,''); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+isnull(@ERROR_PRED_MESSAGE,''); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+isnull(@ERROR_NUMBER,''); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+isnull(@ERROR_MESSAGE,''); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+rep.GetDateFormat(@StartDate, predeterminado)+' '+rep.GetTimeFormat(@StartDate, predeterminado); //cast(@StartDate como nvarchar(max)); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+rep.GetDateFormat(@FinishDate, predeterminado)+' '+rep.GetTimeFormat(@FinishDate, predeterminado); //cast(@FinishDate como nvarchar(max)); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+cast(@Count as nvarchar(max)); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+isnull(@ERROR_LINE,''); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+isnull(@ERROR_PROCEDURE,''); establecer @[email protected]+''; establecer @[email protected]+''; establecer @[email protected]+isnull(@ERROR_POST_MESSAGE,''); establecer @[email protected]+''; eliminar de @tbl donde [email protected]; establecer @[email protected]+''; conjunto final @[email protected]+''; selecciona @cuerpo;ENDGO

[/expandir]

10. Cree un procedimiento almacenado que envíe mensajes:

[expandir título =”Código”]

USE [DATABAE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[RunErrorInfoProc] @IsRealTime bit =0 // modo de envío (1-tiempo real) ASBEGIN /* enviar notificaciones de error con el modo especificado */ SET NOCOUNT ON; declarar @dt datetime=getdate(); declarar @tbl table(Destinatarios nvarchar(max)); declarar @recipients nvarchar(max); declarar @recipient nvarchar(255); declarar @result nvarchar(max)=''; declarar @recp nvarchar(max); declarar @ind int; declarar @recipients_key nvarchar(max); // recibir todos los mensajes necesarios insertar en @tbl(Destinatarios) seleccionar [DESTINATARIOS] de srv.ErrorInfo donde InsertDate0) begin //recibir destinatarios select top (1) @recipients=Destinatarios de @tbl; establecer @[email protected]; establecer @resultado=''; // para cada destinatario while(len(@recipients)>0) begin set @ind=CHARINDEX(';', @recipients); if(@ind>0) begin set @recipient=substring(@recipients,1, @ind-1); establecer @recipients=substring(@recipients,@ind+1,len(@recipients)[email protected]); end else begin set @[email protected]; establecer @destinatarios=''; fin; // recibir los correos electrónicos de los destinatarios exec [srv].[GetRecipients] @[email protected], @[email protected] out; if(len(@recp)=0) begin exec [srv].[GetRecipients] @[email protected], @[email protected] out; if(len(@recp)=0) set @[email protected]; end // separados por el símbolo ';' establecer @[email protected]@sqldat.com+';'; end set @result=substring(@result,1,len(@result)-1); establecer @[email protected]; // recibe el informe HTML con los destinatarios especificados y la inserción de la fecha en @rec_body(Body) exec srv.GetHTMLTable @[email protected]_key, @[email protected]; // recibe el informe HTML select top (1) @body=Body from @rec_body; // el EXEC de envío real msdb.dbo.sp_send_dbmail // perfil de administrador de correo electrónico que creamos @profile_name ='ALARM', // correo electrónico del destinatario @recipients =@recipients, // texto de un mensaje @body =@body, // Asunto @subject =N'INFORMACIÓN SOBRE ERRORES DE EJECUCIÓN', @body_format='HTML'--, // Por ejemplo, agreguemos los resultados de una consulta SQL aleatoria al mensaje [email protected] =@query--'SELECT TOP 10 nombre DESDE sys.objetos'; eliminar de @tbl donde [email protected]_key; eliminar de @rec_body; end // archivar los mensajes enviados INSERTAR EN [srv].[ErrorInfoArchive] ([ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] ,[ DESTINATARIOS] ,[StartDate] ,[FinishDate] ,[Count] ,IsRealTime ) SELECT [ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] , [RECIPIENTS] ,[StartDate] ,[FinishDate] ,[Count] ,IsRealTime FROM [srv].[ErrorInfo] where [email protected] e InsertDate 

[/expandir]

Este procedimiento almacenado toma cada mensaje de la cola de mensajes y lo envuelve en un informe HTML en forma de tabla. Para los destinatarios, en función de su código o dirección de correo electrónico principal, crea una cadena que consta de direcciones de correo electrónico a las que se envía un mensaje. De esta forma, se procesan todos los mensajes seleccionados. Aquí se utiliza el procedimiento almacenado msdb.dbo.sp_send_dbmail.

11. Cree dos tareas en Agent (la primera es para notificaciones en tiempo real (programar 1 vez por minuto), la segunda es para notificaciones simples (programar 1 vez por hora)). Agregue lo siguiente al código de la tarea:

EJECUTAR [DATABASE_NAME].[srv].[RunErrorInfoProc] @IsRealTime=0; // 0 - para mensajes simples y 1 - para mensajes en tiempo real

Este es un ejemplo de notificación de errores:

[expandir título=”Código”]

empezar try exec [DATABASE_NAME].[srv].[KillFullOldConnect];fin trybegin catch declare @str_mess nvarchar(max)=ERROR_MESSAGE(), @str_num nvarchar(max)=cast(ERROR_NUMBER() as nvarchar(max) ), @str_line nvarchar(max)=cast(ERROR_LINE() as nvarchar(max)), @str_proc nvarchar(max)=ERROR_PROCEDURE(), @str_title nvarchar(max)='ELIMINAR PROCESOS QUE NO RESPONDEN EN EL SERVIDOR' ejemplo @sqldat.com@servername, @str_pred_mess nvarchar(max)='EL ERROR DE ELIMINACIÓN DE PROCESOS QUE NO RESPONDEN OCURRIÓ EN EL SERVIDOR '[email protected]@servername+'; exec [DATABASE_NAME].srv.ErrorInfoIncUpd @ERROR_TITLE =@str_title, @ERROR_PRED_MESSAGE =@str_pred_mess, @ERROR_NUMBER =@str_num, @ERROR_MESSAGE =@str_mess, @ERROR_LINE =@str_line, @ERROR_PROCEDURE =@str_proc, @ERROR_POST_MESSAGE =NULL, @ DESTINATARIOS ='RECIPIENTE1;RECIPIENTE2'; declarar @err [email protected]@error; raiserror(@str_mess,16,1);fin de atrapar

[/expandir]

Aquí, se utiliza el procedimiento almacenado svr.KillFullOldConnect.

Resultado

Este artículo incluye un ejemplo de la extensión de la funcionalidad de un correo de base de datos regular y un ejemplo de cómo generar notificaciones en tablas HTML y luego enviarlas por correo electrónico a los administradores. Este enfoque permite notificar a los administradores sobre diferentes problemas en tiempo real o después de un cierto tiempo, minimizando así la ocurrencia de un problema crítico y la falla del DBMS y el servidor, lo que a su vez protege la producción del retraso en el flujo de trabajo.

Referencias:

  1. Sp_send_dbmail
  2. Correo de base de datos
  3. Srv.KillFullOldConnect