Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Configurazione delle notifiche di posta elettronica database in MS SQL Server

Introduzione

Spesso è necessario informare in qualche modo gli amministratori sui problemi con un server. Le notifiche sono generalmente divise in 2 tipi:

1) notifiche in tempo reale, ovvero quelle che devono arrivare immediatamente quando si verifica un problema

2) notifiche ritardate, ovvero quelle che arrivano dopo un tempo abbastanza lungo (più di 1 ora) dal verificarsi di un problema.

Nel mio lavoro, era necessario estendere le funzionalità della normale posta elettronica di database di SQL Server.

In questo articolo considereremo un esempio di come generare notifiche nelle tabelle HTML e inviarle agli amministratori.

Soluzione

1. Configura Posta Database

2. Crea una tabella per i destinatari:

[expand title =”Codice”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Destinatario]( [GUID_destinatario] [identificatore univoco] ROWGUIDCOL NOT NULL, [Nome_destinatario] [nvarchar](255) NOT NULL, // un'e-mail principale del destinatario [ Recipient_Code] [nvarchar](10) NOT NULL, // il codice del destinatario [IsDeleted] [bit] NOT NULL, // un indicatore di eliminazione (se un destinatario è utilizzato o meno) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Recipient ] CHIAVE PRIMARIA CLUSTERED ( [GUID_destinatario] ASC)CON (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY], CONSTRAINT [AK_Recipient_Code] UNICO NON CLUSTERED ( [Codice_destinatario] ASC)CON (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY], CONSTRAINT [AK_Nome_destinatario] UNICO NON CLUSTERED ([Nome_destinatario] ASC)CON (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OF F, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]TABELLA DEL GOALTER [srv].[Destinatario] AGGIUNGI VINCOLI [GUID_destinatario_destinatario_DF] PREDEFINITO (newssequentialid()) PER [GUID_destinatario]TABELLA DEL GOALTER [ srv].[Destinatario] ADD CONSTRAINT [DF_Recipient_IsDeleted] DEFAULT ((0)) PER [IsDeleted]GOALTER TABLE [srv].[Destinatario] ADD CONSTRAINT [DF_Recipient_InsertUTCDate] DEFAULT (getutcdate()) PER [InsertUTCDate]GO

[/expand]

3. Crea una tabella per gli indirizzi dei destinatari:

[expand title =”Codice”]

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 [Address] [nvarchar]( 255) NOT NULL, // email [IsDeleted] [bit] NOT NULL, // indicatore di eliminazione (se l'email è utilizzata o meno) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED ( [Address_GUID] ASC )CON (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY], CONSTRAINT [AK_Address] UNIQUE NON CLUSTERED ( [Recipient_GUID] ASC, [Address] ASC)CON (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 (newssequentialid()) PER [Address_GUID] TABELLA DEI PORTIERI [ srv].[Address] ADD CONSTRAINT [DF_Address_IsDeleted] DEFAULT ((0)) PER [IsDeleted]GOALTER TABLE [srv].[Address] ADD CONSTRAINT [DF_Address_InsertUTCDate] DEFAULT (getutcdate()) PER [InsertUTCDate]GO

[/expand]

4. Crea una tabella per una coda di messaggi:

[expand title =”Codice”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfo]( [ErrorInfo_GUID] [uniqueidentifier] NOT NULL, [ERROR_TITLE] [nvarchar](max) NULL, // title [ERROR_PRED_MESSAGE] [nvarchar] (max) NULL, // informazioni preliminari [ERROR_NUMBER] [nvarchar](max) NULL, // codice messaggio (errore) [ERROR_MESSAGE] [nvarchar](max) NULL, // messaggio [ERROR_LINE] [nvarchar](max) NULL, // numero di riga [ERROR_PROCEDURE] [nvarchar](max) NULL, // stored procedure [ERROR_POST_MESSAGE] [nvarchar](max) NULL, // informazioni esplicative [RECIPIENTS] [nvarchar](max) NULL, // destinatari separati da ';' [InsertDate] [datetime] NOT NULL, [StartDate] [datetime] NOT NULL, // data e ora di inizio [FinishDate] [datetime] NOT NULL, // data e ora di fine [Count] [int] NOT NULL, // numero di volte [UpdateDate] [dat etime] NOT NULL, [IsRealTime] [bit] NOT NULL, // indicatore in tempo reale [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] AGGIUNGI CONSTRAINT [DF_ErrorInfo_ErrorInfo_GUID] PREDEFINITO (newid()) PER [ErrorInfo_GUID]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_InsertDate] PREDEFINITO (getdate()) PER [InsertDate]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_StartDate] DEFAULT (getdate()) PER [StartDate]GOALTER TABLE [ srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_FinishDate] DEFAULT (getdate()) PER [FinishDate]GOALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_Count] DEFAULT ((1)) PER [Count]GOALTER TABLE [srv] .[ErrorInfo] AGGIUNGI VINCOLO [DF__ErrorInfo__Updat__5FFEE747] DEFAU LT (getdate()) PER [UpdateDate]TABELLA DEL GOALTER [srv].[ErrorInfo] AGGIUNGI VINCOLO [DF_ErrorInfo_IsRealTime] PREDEFINITO ((0)) PER [IsRealTime]TABELLA DEL GOALTER [srv].[ErrorInfo] AGGIUNGI VINCOLO [DF_ErrorInfo_InsertUTCDate] PREDEFINITO ( getutcdate()) PER [InsertUTCDate]GO

[/expand]

5. Crea una tabella di archivio per i messaggi inviati dalla coda dei messaggi:

[expand title =”Codice”]

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, CONSTRAINT [PK_ArchiveErrorInfo] CHIAVE PRIMARIA CLUSTERED ( [ErrorInfo_GUID] ASC)CON (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] ADD CONSTRAINT [DF_ErrorInfoArchive_ErrorInfo_GUID] DEFAULT (newssequentialid()) PER [ErrorInfo_GUID]GOALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ArchiveErrorInfo_InsertDate] DEFAULT (getdate()) PER [InsertDate]GOALTER TABLE [srv].[ErrorInfoArchive] AGGIUNGI CONSTRAINT [DF_ErrorInfoArchive_StartDate] PREDEFINITO (getdate()) PER [StartDate]TABELLA DEL GOALTER [srv].[ErrorArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_FinishDate] PREDEFINITO (getdate()) PER [FinishDate]TABELLA DEL GOALTER [srv ].[ErrorInfoArchive] AGGIUNGI CONSTRAINT [DF_ErrorInfoArchive_Count] PREDEFINITO ((1)) PER [Conteggio]TABELLA DEL GOALTER [srv].[ErrorInfoArchive] AGGIUNGI CONSTRAINT [DF_ErrorInfoArchive_Update] PREDEFINITO (getdate()) PER [UpdateDate]TABELLA DEL GOALTER [srv]. [ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_IsRealTime] DEFAULT ((0)) PER [IsRealTime]GOALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_InsertUTCDate] DEFAULT (getutcdate()) PER [InsertUTCDate]GO

[/expand]

Queste informazioni sono necessarie per la cronologia. Inoltre, questa tabella deve essere cancellata da dati molto vecchi (ad esempio, più vecchi di un mese).

6. Crea una procedura memorizzata che registra un nuovo messaggio nella coda dei messaggi:

[expand title =”Codice”]

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 /* Errore durante la registrazione dell'errore tabella da inviare via email se la tabella ha già una voce con lo stesso titolo, contenuto e mittente, la data di fine dell'errore, la data di aggiornamento del record, nonché il numero di errori cambieranno */ SET NOCOUNT SU; dichiarare @ErrorInfo_GUID identificatore univoco; seleziona top 1 @ErrorInfo_GUID=ErrorInfo_GUID da srv.ErrorInfo dove (example@sqldat.com_TITLE o @ERROR_TITLE è nullo) e example@sqldat.com e (example@sqldat.com_MESSAGE o @ERROR_MESSAGE è null) e (example@sqldat.com_PRED_MESSAGE o @ERROR_PRED_MESSAGE è null) e (example@sqldat.com_POST_MESSAGE o @ERROR_POST_MESSAGE è null) e (example@sqldat.com o @IsRealTime è null); if(@ErrorInfo_GUID is null) inizia a inserire in srv.ErrorInfo ( ERROR_TITLE ,ERROR_PRED_MESSAGE ,ERROR_NUMBER ,ERROR_MESSAGE ,ERROR_MESSAGE ,ERROR_LINE ,ERROR_PROCEDURE ,ERROR_POST_MESSAGE ,RECIPIENTS ,IsRealTime ,StartDate ,FinishDate ) select @ERROR_TITLE ,@ERROR_PRED_MESSAGE ,@ERRORMESS_NUMBER ERROR_LINE ,@ERROR_PROCEDURE ,@ERROR_POST_MESSAGE ,@RECIPIENTS ,@IsRealTime ,isnull(@StartDate, getdate()) ,isnull(@FinishDate,getdate()) fine altrimenti inizia l'aggiornamento srv.ErrorInfo set FinishDate=getdate(), [Count]=[Count]+1, UpdateDate=getdate() where example@sqldat.com_GUID; endENDGO

[/expand]

7. Crea una stored procedure che restituisca una stringa dagli indirizzi tramite il codice o l'indirizzo email principale di un destinatario:

[expand title =”Codice”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetRecipients]@Nome_destinatario nvarchar(255)=NULL,@Codice_destinatario nvarchar(10)=NULL,@destinatario nvarchar(max) out/* La procedura per creazione di notifiche e-mail*/ASBEGIN SET NOCOUNT ON; imposta @Destinatari=''; seleziona @example@sqldat.com+d.[Indirizzo]+';' from srv.Recipient as r inner join srv.[Address] as d on r.Recipient_GUID=d.Recipient_GUID dove (example@sqldat.com_Name or @Recipient_Name IS NULL) e (example@sqldat.com_Code or @Recipient_Code IS NULL) e r.IsDeleted=0 e d.IsDeleted=0; --order by r.InsertUTCDate desc, d.InsertUTCDate desc; if(len(@Destinatari)>0) set @Destinatari=substring(@Destinatari,1,len(@Destinatari)-1);ENDGO

[/expand]

8. Crea le funzioni necessarie per lavorare con date e ora:

[expand title =”Codice”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [rep].[GetDateFormat] ( @dt datetime, // input date @format int=0 // preset format)RETURNS nvarchar(255)AS/* Restituisce la data come una stringa secondo il formato specificato e la data di input Inserisce degli zeri ove necessario:format data di input risultato 0 17.4.2014 "17.04.2014" 1 17.4.2014 "04.2014" 1 8.11.2014 "11.2014" 2 17.04.2014 "2014" */INIZIA A DICHIARARE @res nvarchar(255); DICHIARA @giorno int=GIORNO(@dt); DICHIARA @mese int=MESE(@dt); DICHIARA @anno int=ANNO(@dt); if(@format=0) begin set @res=IIF(@day<10,'0'+cast(@day as nvarchar(1)), cast(@day as nvarchar(2)))+'.'; set @example@sqldat.com+IIF(@mese<10,'0'+cast(@mese come nvarchar(1)), cast(@mese come nvarchar(2)))+'.'; set @example@sqldat.com+cast(@year as nvarchar(255)); end else if(@format=1) begin set @res=IIF(@mese<10,'0'+cast(@mese come nvarchar(1)), cast(@mese come nvarchar(2)))+'. '; set @example@sqldat.com+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, // input time @format int=0 // preset format)RETURNS nvarchar(255)AS/* Returns ora come stringa secondo il formato specificato e l'ora di input Inserisce zeri dove necessario:format input time result 0 17:04 "17:04:00" 1 17:04 "17:04" 1 8:04 "08:04 " 2 17:04 "17"*/INIZIA A DICHIARARE @res nvarchar(255); DICHIARA @hour int=DATEPART(HOUR, @dt); DICHIARA @min int=DATEPART(MINUTE, @dt); DICHIARA @sec int=DATAPART(SECONDA, @dt); if(@format=0) begin set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2)))+':'; set @example@sqldat.com+IIF(@min<10,'0'+cast(@min as nvarchar(1)), cast(@min as nvarchar(2)))+':'; set @example@sqldat.com+IIF(@sec<10,'0'+cast(@sec come nvarchar(1)), cast(@sec come 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 @example@sqldat.com+IIF(@min<10,'0'+cast(@min come nvarchar(1)), cast(@min come nvarchar(2))); end else if(@format=2) begin set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2))); end RETURN @res;ENDGO

[/expand]

9. Crea una procedura memorizzata che crea un report HTML sui messaggi sotto forma di tabella:

[expand title =”Codice”]

USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetHTMLTable] @recipients nvarchar(max) ,@dt datetime // entro quale data leggereASBEGIN /* genera codice HTML per la tabella */ SET NOCOUNT ON; dichiarare @body nvarchar(max); dichiara @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 ); dichiara @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 insert in @tbl( [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE ] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] ) seleziona i primi 100 [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] from [srv].[ErrorInfo] dove ([RECIPIENTS]example@sqldat.com ) o (@recipients IS NULL) e InsertDate'; set @example@sqldat.com+''; imposta @example@sqldat.com+'№ п/п'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'DATE'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'ERRORE'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+'DESCRIZIONE'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+'CODICE DI ERRORE'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'MESSAGGIO'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'START'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'FINISH'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'NUMERO'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'NUMERO DI RIGA'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'PROCEDURA'; imposta @example@sqldat.com+''; set @example@sqldat.com+''; imposta @example@sqldat.com+'NOTA'; imposta @example@sqldat.com+''; imposta @example@sqldat.com+''; while((seleziona i primi 1 1 da @tbl)>0) inizia set @example@sqldat.com+''; seleziona i primi 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; set @example@sqldat.com+''; imposta @example@sqldat.com+cast(@ID come nvarchar(max)); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+rep.GetDateFormat(@InsertDate, default)+' '+rep.GetTimeFormat(@InsertDate, default); // cast(@InsertDate as nvarchar(max)); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_TITLE,''); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_PRED_MESSAGE,''); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_NUMBER,''); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_MESSAGE,''); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+rep.GetDateFormat(@StartDate, predefinito)+' '+rep.GetTimeFormat(@StartDate, predefinito); //cast(@StartDate as nvarchar(max)); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+rep.GetDateFormat(@FinishDate, predefinito)+' '+rep.GetTimeFormat(@FinishDate, predefinito); //cast(@FinishDate as nvarchar(max)); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+cast(@Count as nvarchar(max)); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_LINE,''); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_PROCEDURE,''); imposta @example@sqldat.com+''; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_POST_MESSAGE,''); imposta @example@sqldat.com+''; elimina da @tbl dove esempio@sqldat.com; imposta @example@sqldat.com+''; end set @example@sqldat.com+''; seleziona @body;ENDGO

[/expand]

10. Crea una procedura memorizzata che invii messaggi:

[expand title =”Codice”]

USE [DATABAE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[RunErrorInfoProc] @IsRealTime bit =0 // modalità di invio (1-tempo reale)ASBEGIN /* invio di notifiche di errore con la modalità specificata */ SET NOCOUNT ON; dichiara @dt datetime=getdate(); dichiarare @tbl table(Destinatari nvarchar(max)); dichiara @recipients nvarchar(max); dichiara @recipient nvarchar(255); dichiara @result nvarchar(max)=''; dichiara @recp nvarchar(max); dichiara @ind int; dichiarare @recipients_key nvarchar(max); // ricevi tutti i messaggi necessari inserisci in @tbl(Destinatari) seleziona [DESTINATARI] da srv.ErrorInfo dove InserisciDate0) inizia //ricevi i destinatari seleziona i primi (1) @recipients=Destinatari da @tbl; imposta @example@sqldat.com; imposta @risultato=''; // per ogni destinatario 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)example@sqldat.com); fine altrimenti inizia set @example@sqldat.com; imposta @destinatario=''; fine; // ricevere le email dei destinatari exec [srv].[GetRecipients] @example@sqldat.com, @example@sqldat.com out; if(len(@recp)=0) inizia exec [srv].[GetRecipients] @example@sqldat.com, @example@sqldat.com out; if(len(@recp)=0) set @example@sqldat.com; fine // separato dal simbolo ';' set @example@sqldat.comexample@sqldat.com+';'; end set @result=substring(@result,1,len(@result)-1); imposta @example@sqldat.com; // riceve il report HTML con i destinatari specificati e la data inserita in @rec_body(Body) exec srv.GetHTMLTable @example@sqldat.com_key, @example@sqldat.com; // ricevi report HTML seleziona top (1) @body=Body da @rec_body; // l'effettivo EXEC di invio msdb.dbo.sp_send_dbmail // il profilo dell'amministratore dell'e-mail che abbiamo creato @profile_name ='ALARM', //e-mail del destinatario @recipients =@recipients, // testo di un messaggio @body =@body, // Oggetto @subject =N'INFORMATION ON EXECUTION ERRORS', @body_format='HTML'--, // Ad esempio, aggiungiamo i risultati di una query SQL casuale al messaggio example@sqldat.com =@query--'SELECT TOP 10 nome DA sys.objects'; elimina da @tbl dove esempio@sqldat.com_key; elimina da @rec_body; end // archivia i messaggi inviati INSERT INTO [srv].[ErrorInfoArchive] ([ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] ,[ DESTINATARI] ,[StartDate] ,[FinishDate] ,[Count] ,IsRealTime ) SELECT [ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] , [DESTINATARI] ,[StartDate] ,[FinishDate] ,[Count] ,IsRealTime FROM [srv].[ErrorInfo] dove example@sqldat.com e InsertDate 

[/expand]

Questa procedura memorizzata prende ogni messaggio dalla coda dei messaggi e lo racchiude in un report HTML sotto forma di tabella. Per i destinatari, in base al loro codice o indirizzo email principale, crea una stringa composta da indirizzi email, a cui viene inviato un messaggio. In questo modo vengono elaborati tutti i messaggi selezionati. Qui viene utilizzata la procedura memorizzata msdb.dbo.sp_send_dbmail.

11. Crea due attività in Agent (la prima è per le notifiche in tempo reale (programma 1 volta al minuto), la seconda è per le notifiche semplici (programma 1 volta all'ora)). Aggiungi quanto segue al codice dell'attività:

ESEGUI [NOME_DATABASE].[srv].[RunErrorInfoProc] @IsRealTime=0; // 0 - per messaggi semplici e 1 - per messaggi in tempo reale

Ecco un esempio di segnalazione degli errori:

[expand title="Codice"]

comincia a provare exec [DATABASE_NAME].[srv].[KillFullOldConnect];end trybegin catch dichiarare @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)='ELIMINAZIONE DEI PROCESSI CHE NON RISPONDONO SUL SERVER 'example @sqldat.com@nomeserver, @str_pred_mess nvarchar(max)='LA CANCELLAZIONE DELL'ERRORE DI PROCESSO CHE NON RISPONDE SI È VERIFICATA SUL SERVER 'example@sqldat.com@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, @ DESTINATARI ='DESTINATARIO1;DESTINATARIO2'; dichiara @err esempio@sqldat.com@errore; raiserror(@str_mess,16,1);fine cattura

[/expand]

Qui viene utilizzata la procedura memorizzata svr.KillFullOldConnect.

Risultato

Questo articolo include un esempio di estensione della funzionalità di una normale posta elettronica database e un esempio di come generare notifiche nelle tabelle HTML e quindi inviarle tramite posta elettronica agli amministratori. Questo approccio consente di notificare agli amministratori diversi problemi in tempo reale o dopo un certo tempo, riducendo così al minimo il verificarsi di un problema critico e il guasto di DBMS e server, che a sua volta protegge la produzione dal ritardo del flusso di lavoro.

Riferimenti:

  1. Sp_send_dbmail
  2. Posta database
  3. Srv.KillFullOldConnect