Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Configuration des notifications de messagerie de base de données dans MS SQL Server

Présentation

Souvent, il est nécessaire d'informer d'une manière ou d'une autre les administrateurs des problèmes rencontrés avec un serveur. Les notifications sont généralement divisées en 2 types :

1) les notifications en temps réel, c'est-à-dire celles qui doivent arriver immédiatement lorsqu'un problème survient

2) les notifications retardées, c'est-à-dire celles qui arrivent après un délai assez long (plus d'1h) après qu'un problème se soit produit.

Dans mon travail, il était nécessaire d'étendre les fonctionnalités de la messagerie de base de données SQL Server standard.

Dans cet article, nous examinerons un exemple de génération de notifications dans des tableaux HTML, puis de les envoyer aux administrateurs.

Solution

1. Configurer la messagerie de la base de données

2. Créez un tableau pour les destinataires :

[expand title =”Code”]

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, // une adresse e-mail principale du destinataire [ Recipient_Code] [nvarchar](10) NOT NULL, // code du destinataire [IsDeleted] [bit] NOT NULL, // un indicateur de suppression (qu'un destinataire soit utilisé ou non) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Recipient ] PRIMARY KEY CLUSTERED ( [Recipient_GUID] ASC)AVEC (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY], CONTRAINTE [AK_Recipient_Code] UNIQUE NONCLUSTERED ( [Recipient_Code] ASC)AVEC (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY], CONTRAINTE [AK_Recipient_Name] UNIQUE NONCLUSTERED ( [Recipient_Name] ASC)AVEC (PAD_INDEX =OFF, STATISTICS_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 (newsequentialid()) FOR [Recipient_GUID]GOALTER TABLE [ srv].[Recipient] ADD CONSTRAINT [DF_Recipient_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]GOALTER TABLE [srv].[Recipient] ADD CONSTRAINT [DF_Recipient_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]GO

[/expand]

3. Créez un tableau pour les adresses des destinataires :

[expand title =”Code”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Address]( [Address_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL, [Recipient_GUID] [uniqueidentifier] NOT NULL, // destinataire [Address] [nvarchar]( 255) NOT NULL, // email [IsDeleted] [bit] NOT NULL, // indicateur de suppression (que l'email soit utilisé ou non) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED ( [Address_GUID] ASC )WITH (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY], CONSTRAINT [AK_Address] UNIQUE NONCLUSTERED ( [Recipient_GUID] ASC, [Address] ASC)WITH (PAD_INDEX =OFF , 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 (newsequentialid()) FOR [Address_GUID] TABLEAU DES BUTEURS [ srv].[Address] ADD CONSTRAINT [DF_Address_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]GOALTER TABLE [srv].[Address] ADD CONSTRAINT [DF_Address_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]GO

[/expand]

4. Créez une table pour une file d'attente de messages :

[expand title =”Code”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfo]( [ErrorInfo_GUID] [uniqueidentifier] NOT NULL, [ERROR_TITLE] [nvarchar](max) NULL, // titre [ERROR_PRED_MESSAGE] [nvarchar] (max) NULL, // informations préliminaires [ERROR_NUMBER] [nvarchar](max) NULL, // message (erreur) code [ERROR_MESSAGE] [nvarchar](max) NULL, // message [ERROR_LINE] [nvarchar](max) NULL, // numéro de ligne [ERROR_PROCEDURE] [nvarchar](max) NULL, // procédure stockée [ERROR_POST_MESSAGE] [nvarchar](max) NULL, // informations explicatives [RECIPIENTS] [nvarchar](max) NULL, // destinataires séparés par ';' [InsertDate] [datetime] NOT NULL, [StartDate] [datetime] NOT NULL, // données et heure de début [FinishDate] [datetime] NOT NULL, // date et heure de fin [Count] [int] NOT NULL, // nombre de fois [UpdateDate] [dat etime] NOT NULL, [IsRealTime] [bit] NOT NULL, // indicateur de temps réel [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] AJOUTER LA CONTRAINTE [DF_ErrorInfo_InsertDate] DEFAULT (getdate()) POUR [InsertDate]GOALTER TABLE [srv].[ErrorInfo] AJOUTER LA CONTRAINTE [DF_ErrorInfo_StartDate] DEFAULT (getdate()) FOR [StartDate]GOALTER TABLE [ srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_FinishDate] DEFAULT (getdate()) FOR [FinishDate]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_Count] DEFAULT ((1)) FOR [Count]GOALTER TABLE [srv] .[ErrorInfo] AJOUTER CONTRAINTE [DF__ErrorInfo__Updat__5FFEE747] DEFAU LT (getdate()) FOR [UpdateDate]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_IsRealTime] DEFAULT ((0)) FOR [IsRealTime]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_InsertUTCDate] DEFAULT ( getutcdate()) FOR [InsertUTCDate]GO

[/expand]

5. Créez une table d'archives pour les messages envoyés depuis la file d'attente des messages :

[expand title =”Code”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfoArchive]( [ErrorInfo_GUID] [uniqueidentifier] 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, CONTRAINTE [PK_ArchiveErrorInfo] PRIMARY KEY CLUSTERED ( [ErrorInfo_GUID] ASC)AVEC (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]GOALTE R TABLE [srv].[ErrorInfoArchive] AJOUTER LA CONTRAINTE [DF_ErrorInfoArchive_ErrorInfo_GUID] DEFAULT (newsequentialid()) POUR [ErrorInfo_GUID]GOALTER TABLE [srv].[ErrorInfoArchive] AJOUTER LA CONTRAINTE [DF_ArchiveErrorInfo_InsertDate] DEFAULT (getdate()) FOR [InsertDate]GOALTER TABLE [srv].[ErrorInfoArchive] AJOUTER LA CONTRAINTE [DF_ErrorInfoArchive_StartDate] DEFAULT (getdate()) POUR [StartDate]GOALTER TABLE [srv].[ErrorInfoArchive] AJOUTER LA CONTRAINTE [DF_ErrorInfoArchive_FinishDate] DEFAULT (getdate()) FOR [FinishDate]GOALTER TABLE [srv] ].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_Count] DEFAULT ((1)) FOR [Count]GOALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_UpdateDate] DEFAULT (getdate()) FOR [UpdateDate]GOALTER TABLE [srv]. [ErrorInfoArchive] AJOUTER LA CONTRAINTE [DF_ErrorInfoArchive_IsRealTime] DEFAULT ((0)) FOR [IsRealTime]GOALTER TABLE [srv].[ErrorInfoArchive] AJOUTER LA CONTRAINTE [DF_ErrorInfoArchive_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]GO

[/expand]

Cette information est nécessaire pour l'historique. En outre, ce tableau doit être effacé des données très anciennes (par exemple, datant de plus d'un mois).

6. Créez une procédure stockée qui enregistre un nouveau message dans la file d'attente des messages :

[expand title =”Code”]

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 /* Erreur lors de la journalisation de l'erreur table à envoyer par email si la table a déjà une entrée avec le même titre, contenu et expéditeur, la date de fin de l'erreur, la date de mise à jour de l'enregistrement ainsi que le nombre d'erreurs changeront */ SET NOCOUNT SUR; déclarer @ErrorInfo_GUID identifiant unique ; sélectionnez top 1 @ErrorInfo_GUID=ErrorInfo_GUID de srv.ErrorInfo où ([email protected]_TITLE ou @ERROR_TITLE est nul) et [email protected] et ([email protected]_MESSAGE ou @ERROR_MESSAGE est nul) et ([email protected]_PRED_MESSAGE ou @ERROR_PRED_MESSAGE est nul) et ([email protected]_POST_MESSAGE ou @ERROR_POST_MESSAGE est nul) et ([email protected] ou @IsRealTime est nul); if (@errorinfo_guid est null) commencez à insérer dans srv.errorinfo (error_title, error_pred_message, error_number, error_message, error_line, error_procedure, error_post_message, récipient, isRealtime, startDate, final) 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

[/expand]

7. Créez une procédure stockée qui renvoie une chaîne à partir des adresses par le code ou l'adresse e-mail principale d'un destinataire :

[expand title =”Code”]

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/* La procédure pour création de notifications par e-mail*/ASBEGIN SET NOCOUNT ON ; définir @Recipients='' ; sélectionnez @[email protected]+d.[Adresse]+';' 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) et r.IsDeleted=0 et d.IsDeleted=0 ; --order by r.InsertUTCDate desc, d.InsertUTCDate desc ; if(len(@Recipients)>0) set @Recipients=substring(@Recipients,1,len(@Recipients)-1);ENDGO

[/expand]

8. Créez les fonctions nécessaires pour travailler avec les dates et l'heure :

[expand title =”Code”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [rep].[GetDateFormat] ( @dt datetime, // date d'entrée @format int=0 // format prédéfini)RETURNS nvarchar(255)AS/* Renvoie la date sous une chaîne selon le format spécifié et la date d'entrée Insère des zéros si nécessaire :format date d'entrée résultat 0 */BEGIN DECLARE @res nvarchar(255); DECLARE @day int=DAY(@dt); DÉCLARER @mois int=MOIS(@dt); DÉCLARER @année int=ANNÉE(@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)))+'.'; set @[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)))+'. '; set @[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, // heure d'entrée @format int=0 // format prédéfini)RETURNS nvarchar(255)AS/* Renvoie heure sous forme de chaîne selon le format spécifié et l'heure d'entrée Insère des zéros si nécessaire :format heure d'entrée résultat 0 17:04 "17:04:00" 1 17:04 "17:04" 1 8:04 "08:04 " 2 17:04 "17"*/BEGIN DECLARE @res nvarchar(255); DÉCLARER @heure int=DATEPART(HEURE, @dt); DECLARE @min int=DATEPART(MINUTE, @dt); DECLARE @sec int=DATEPART(SECOND, @dt); if(@format=0) begin set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2)))+':'; set @[email protected]+IIF(@min<10,'0'+cast(@min as nvarchar(1)), cast(@min as nvarchar(2)))+':'; set @[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)))+' :'; set @[email protected]+IIF(@min<10,'0'+cast(@min as nvarchar(1)), cast(@min as 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 RETURN @res;ENDGO

[/expand]

9. Créez une procédure stockée qui crée un rapport HTML sur les messages sous forme de tableau :

[expand title =”Code”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetHTMLTable] @recipients nvarchar(max) ,@dt datetime // à quelle date lireASBEGIN /* génère du code HTML pour la table */ SET NOCOUNT ON; déclarer @body nvarchar(max); déclarer @tbl table(ID int identity(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 ); déclarer @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 (max) ,@InsertDate datetime ,@StartDate datetime ,@FinishDate datetime ,@Count int insérer dans @tbl( [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE ] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] ) sélectionnez les 100 premiers [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] from [srv].[ErrorInfo] où ([RECIPIENTS][email protected] ) ou (@recipients IS NULL) et InsertDate' ; set @[email protected]+'' ; set @[email protected]+'№ ï/ï' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'DATE' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'ERREUR' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'DESCRIPTION' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'CODE D'ERREUR' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'MESSAGE' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'START' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'FINISH' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'NUMBER' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'NUMERO DE LIGNE' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'PROCEDURE' ; set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+'NOTE' ; set @[email protected]+'' ; set @[email protected]+'' ; while((select top 1 1 from @tbl)>0) begin set @[email protected]+'' ; sélectionnez le premier @ID =[ID] ,@ERROR_TITLE =[ERROR_TITLE] ,@ERROR_PRED_MESSAGE=[ERROR_PRED_MESSAGE] ,@ERROR_NUMBER =[ERROR_NUMBER] ,@ERROR_MESSAGE =[ERROR_MESSAGE] ,@ERROR_LINE =[ERROR_PROC] ,@ERROR_PROCEDURE =[ERROR_PROCEDURE ] ,@ERROR_POST_MESSAGE=[ERROR_POST_MESSAGE] ,@InsertDate =[InsertDate] ,@StartDate =[StartDate] ,@FinishDate =[FinishDate] ,@Count =[Count] de la commande @tbl par InsertDate asc ; set @[email protected]+'' ; set @[email protected]+cast(@ID as nvarchar(max)); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+rep.GetDateFormat(@InsertDate, par défaut)+' '+rep.GetTimeFormat(@InsertDate, par défaut); // cast(@InsertDate as nvarchar(max)); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+isnull(@ERROR_TITLE,''); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+isnull(@ERROR_PRED_MESSAGE,''); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+isnull(@ERROR_NUMBER,''); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+isnull(@ERROR_MESSAGE,''); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+rep.GetDateFormat(@StartDate, par défaut)+' '+rep.GetTimeFormat(@StartDate, par défaut); //cast(@StartDate as nvarchar(max)); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+rep.GetDateFormat(@FinishDate, par défaut)+' '+rep.GetTimeFormat(@FinishDate, par défaut); //cast(@FinishDate as nvarchar(max)); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+cast(@Count as nvarchar(max)); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+isnull(@ERROR_LINE,''); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+isnull(@ERROR_PROCEDURE,''); set @[email protected]+'' ; set @[email protected]+'' ; set @[email protected]+isnull(@ERROR_POST_MESSAGE,''); set @[email protected]+'' ; supprimer de @tbl où [email protected] ; set @[email protected]+'' ; end set @[email protected]+'' ; sélectionnez @body;ENDGO

[/expand]

10. Créez une procédure stockée qui envoie des messages :

[expand title =”Code”]

USE [DATABAE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[RunErrorInfoProc] @IsRealTime bit =0 // mode d'envoi (1-temps réel)ASBEGIN /* envoie des notifications d'erreur avec le mode spécifié */ SET NOCOUNT ON; declare @dt datetime=getdate(); declare @tbl table(Recipients nvarchar(max)); déclarer @recipients nvarchar(max); déclarer @recipient nvarchar(255); déclarer @result nvarchar(max)=''; déclarer @recp nvarchar(max); déclarer @ind int ; déclarer @recipients_key nvarchar(max); // recevoir tous les messages nécessaires insérés dans @tbl(Recipients) select [RECIPIENTS] from srv.ErrorInfo where InsertDate0) begin //recevoir les destinataires select top (1) @recipients=Recipients from @tbl; définir @[email protected] ; définir @result='' ; // pour chaque destinataire while(len(@recipients)>0) begin set @ind=CHARINDEX(';', @recipients); if(@ind>0) begin set @recipient=substring(@recipients,1, @ind-1); set @recipients=substring(@recipients,@ind+1,len(@recipients)[email protected]); end else begin set @[email protected] ; set @recipients=''; finir; // reçoit les e-mails des destinataires 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] ; fin // séparé par le symbole ';' set @[email protected]@sqldat.com+';'; end set @result=substring(@result,1,len(@result)-1); définir @[email protected] ; // reçoit le rapport HTML avec les destinataires spécifiés et la date insérée dans @rec_body(Body) exec srv.GetHTMLTable @[email protected]_key, @[email protected] ; // reçoit le rapport HTML select top (1) @body=Body from @rec_body; // l'EXEC d'envoi réel msdb.dbo.sp_send_dbmail // profil d'administrateur d'envoi par e-mail que nous avons créé @profile_name ='ALARM', // e-mail du destinataire @recipients =@recipients, // texte d'un message @body =@body, // Objet @subject =N'INFORMATION ON EXECUTION ERRORS', @body_format='HTML'--, // Par exemple, ajoutons les résultats d'une requête SQL aléatoire au message [email protected] =@query--'SELECT TOP 10 nom FROM sys.objects' ; supprimer de @tbl où [email protected]_key ; supprimer de @rec_body ; end // archive les messages envoyés INSERT INTO [srv].[ErrorInfoArchive] ([ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] ,[ DESTINATAIRES] ,[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] and InsertDate 

[/expand]

Cette procédure stockée extrait chaque message de la file d'attente des messages et l'encapsule dans un rapport HTML sous la forme d'un tableau. Pour les destinataires, en fonction de leur code ou de leur adresse e-mail principale, il crée une chaîne composée d'adresses e-mail, auxquelles un message est envoyé. De cette façon, tous les messages sélectionnés sont traités. Ici, la procédure stockée msdb.dbo.sp_send_dbmail est utilisée.

11. Créez deux tâches dans Agent (la première est pour les notifications en temps réel (planifier 1 fois par minute), la seconde est pour les notifications simples (planifier 1 fois par heure)). Ajoutez ce qui suit au code de la tâche :

EXECUTE [DATABASE_NAME].[srv].[RunErrorInfoProc] @IsRealTime=0 ; // 0 - pour les messages simples et 1 - pour les messages en temps réel

Voici un exemple de rapport d'erreur :

[expand title=”Code”]

begin try exec [DATABASE_NAME].[srv].[KillFullOldConnect];end 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)='SUPPRESSION DES PROCESSUS NON RÉPONDANTS SUR LE SERVEUR' exemple @sqldat.com@servername, @str_pred_mess nvarchar(max)='L'ERREUR DE SUPPRESSION DES PROCESSUS NON RÉPONDANTS S'EST PRODUITE SUR LE SERVEUR '[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, @ DESTINATAIRES ='DESTINATAIRE1;DESTINATAIRE2'; déclarer @err [email protected]@error ; raiserror(@str_mess,16,1);end catch

[/expand]

Ici, la procédure stockée svr.KillFullOldConnect est utilisée.

Résultat

Cet article comprend un exemple d'extension des fonctionnalités d'une messagerie de base de données standard et un exemple de la manière de générer des notifications dans des tableaux HTML, puis de les envoyer par e-mail aux administrateurs. Cette approche permet de notifier les administrateurs de différents problèmes en temps réel ou après un certain temps, minimisant ainsi l'occurrence d'un problème critique et la défaillance du SGBD et du serveur, ce qui à son tour protège la production contre les retards de flux de travail.

Références :

  1. Sp_send_dbmail
  2. Courrier de base de données
  3. Srv.KillFullOldConnect