Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Konfigurowanie powiadomień o poczcie bazy danych w MS SQL Server

Wprowadzenie

Często istnieje potrzeba poinformowania w jakiś sposób administratorów o problemach z serwerem. Powiadomienia są generalnie podzielone na 2 typy:

1) powiadomienia w czasie rzeczywistym, czyli takie, które muszą nadejść natychmiast po wystąpieniu problemu

2) opóźnione powiadomienia, czyli takie, które pojawiają się po dość długim czasie (ponad 1 godzina) od wystąpienia problemu.

W mojej pracy konieczne było rozszerzenie funkcjonalności zwykłej poczty bazy danych SQL Server.

W tym artykule rozważymy przykład generowania powiadomień w tabelach HTML, a następnie wysyłania ich do administratorów.

Rozwiązanie

1. Skonfiguruj pocztę bazy danych

2. Utwórz tabelę dla odbiorców:

[rozwiń tytuł ="Kod"]

 USE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Odbiorca]( [Recipient_GUID] [unikalny identyfikator] ROWGUIDCOL NOT NULL, [Recipient_Name] [nvarchar](255) NOT NULL, // podstawowy adres e-mail odbiorcy Recipient_Code] [nvarchar](10) NOT NULL, // kod odbiorcy [IsDeleted] [bit] NOT NULL, // wskaźnik usunięcia (czy odbiorca jest używany czy nie) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Recipient ] PRIMARY KEY CLUSTERED ( [Recipient_GUID] ASC) Z (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY], CONSTRAINT [AK_EDSC_Code odbiorca_LUS] (PAD_INDEX =WYŁĄCZONE, STATISTICS_NORECOMPUTE =WYŁĄCZONE, IGNORE_DUP_KEY =WYŁĄCZONE, ALLOW_ROW_LOCKS =WŁĄCZONE, ALLOW_PAGE_LOCKS =WŁĄCZONE) WŁĄCZONE [PRIMARY], OGRANICZENIE [AK_Recipient_Name] UNIKALNE NIESKLASTERZOWANE ([Nazwa_odbiorcy] ASC) Z ISTNIEJĄCĄ =WYŁĄCZONE_PAD_MP F, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY] TABELA GOALTERÓW [srv]. [Odbiorca] DODAJ OGRANICZENIE [DF_Recipient_Recipient_GUID] DEFAULT (nowy identyfikator()) TABELA GUID [GOALTER_GUID] srv].[Odbiorca] DODAJ OGRANICZENIE [DF_Recipient_IsDeleted] DOMYŚLNE ((0)) DLA [IsDeleted]TABELA BRAMKARÓW [srv].[Odbiorca] DODAJ OGRANICZENIE [DF_Recipient_InsertUTCDate] DOMYŚLNE (getutcdate()) DLA [GO[/expand]

3. Utwórz tabelę adresów odbiorców:

[rozwiń tytuł ="Kod"]

UŻYJ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv]. [Adres]( [Address_GUID] [unikalny identyfikator] ROWGUIDCOL NIE NULL, [Recipient_GUID] [unikalny identyfikator] NIE NULL, // var [adres] (n 255) NIE NULL, // e-mail [IsDeleted] [bit] NIE NULL, // wskaźnik usunięcia (niezależnie od tego, czy e-mail jest używany, czy nie) [InsertUTCDate] [data i godzina] NIE NULL, OGRANICZENIE [Adres_PK] KLASTRA KLUCZ PODSTAWOWY ( [Address_GUID] ASC ) Z (PAD_INDEX =WYŁĄCZONE, STATISTICS_NORECOMPUTE =WYŁĄCZONE, IGNORE_DUP_KEY =WYŁĄCZONE, ALLOW_ROW_LOCKS =WŁĄCZONE, ALLOW_PAGE_LOCKS =WŁĄCZONE) WŁĄCZONE [PRIMARY], OGRANICZENIE [AK_Address] UNIKALNE NIEROZKLEJONE ([Recipient_GUID] ASC)_WIEX =(Adres) , STATISTICS_NORECOMPUTE =OFF, IGNORE_DUP_KEY =OFF, ALLOW_ROW_LOCKS =ON, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY] TABELA GOALTERÓW [srv]. TABELA BRAMKARZA [ srv].[Adres] DODAJ OGRANICZENIE [DF_Address_IsDeleted] DOMYŚLNE ((0)) DLA [IsDeleted]TABELA GOALTERÓW [srv].[Adres] DODAJ OGRANICZENIE [DF_Address_InsertUTCDate] DOMYŚLNE (getutcdate()) DLA [InsertUTCDate]GO

[/expand]

4. Utwórz tabelę dla kolejki wiadomości:

[rozwiń tytuł ="Kod"]

UŻYJ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfo]( [ErrorInfo_GUID] [unikalny identyfikator] NOT NULL, [ERROR_TITLE] [nvarchar](max) NULL, //AGE_title [_varMOR] (maks.) NULL, // wstępne informacje [ERROR_NUMBER] [nvarchar](maks.) NULL, // komunikat (błędu) kod [ERROR_MESSAGE] [nvarchar](maks.) NULL, // komunikat [ERROR_LINE] [nvarchar](maks.) NULL, // numer wiersza [ERROR_PROCEDURE] [nvarchar](max) NULL, // procedura składowana [ERROR_POST_MESSAGE] [nvarchar](max) NULL, // informacje wyjaśniające [RECIPIENTS] [nvarchar](max) NULL, // recipints oddzielone ';' [InsertDate] [datetime] NOT NULL, [StartDate] [datetime] NOT NULL, // data i godzina rozpoczęcia [DataZakończenia] [datatime] NOT NULL, // data i godzina zakończenia [Count] [int] NOT NULL, // liczba razy [Data aktualizacji] [dat etime] NOT NULL, [IsRealTime] [bit] NOT NULL, // wskaźnik czasu rzeczywistego [InsertUTCDate] [datetime] NULL, CONSTRAINT [PK_ErrorInfo] KLUCZ PODSTAWOWY ([ErrorInfo_GUID] ASC) Z (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE =OFF IGNORE_DUP_KEY =WYŁ, ALLOW_ROW_LOCKS =WŁ, ALLOW_PAGE_LOCKS =WŁ) WŁ [PRIMARY]) WŁ [PRIMARY] TEXTIMAGE_ON [PRIMARY]TABELA GOALTERÓW [srv].[ErrorInfo] DODAJ OGRANICZENIE [DF_ErrorInfo_ErrorInfo_GUIDneorGO] DEFA TABELA [srv].[ErrorInfo] DODAJ OGRANICZENIE [DF_ErrorInfo_InsertDate] DOMYŚLNE (getdate()) DLA [InsertDate] TABELA BRAMKARÓW [srv].[ErrorInfo] DODAJ OGRANICZENIE [DF_ErrorInfo_StartDate] DOMYŚLNE (getdate()) DLA [StartDate]GOAL srv].[ErrorInfo] DODAJ OGRANICZENIE [DF_ErrorInfo_FinishDate] DOMYŚLNE (getdate()) DLA [FinishDate]TABELI BRAMKARÓW [srv].[ErrorInfo] DODAJ OGRANICZENIE [DF_ErrorInfo_Count] DOMYŚLNE ((1)) DLA [Count]TABELI BRAMKARÓW [srv] .[ErrorInfo] DODAJ OGRANICZENIE [DF__ErrorInfo__Updat__5FFEE747] DEFAU LT (getdate()) DLA [UpdateDate]TABELI BRAMKARÓW [srv].[ErrorInfo] DODAJ OGRANICZENIE [DF_ErrorInfo_IsRealTime] DOMYŚLNE ((0)) DLA [IsRealTime]TABELI BRAMKARÓW [srv].[ErrorInfo] DODAJ OGRANICZENIE [DF_ErrorInfo_IsRealTime] DEFAUT getutcdate()) DLA [InsertUTCDate]GO

[/expand]

5. Utwórz tabelę archiwum dla wiadomości wysłanych z kolejki wiadomości:

[rozwiń tytuł ="Kod"]

UŻYJ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABELA [srv]. [ErrorInfoArchive] ( [ErrorInfo_GUID] [unikalny identyfikator] ROWGUIDCOL NIE NULL, [BŁĄD_TYTUŁ] [nvarchar,(nULLER](MARESSOR) NULL ) NULL, [ERROR_NUMBER] [nvarchar](maks.) NULL, [ERROR_MESSAGE] [nvarchar](maks.) NULL, [ERROR_LINE] [nvarchar](maks.) NULL, [ERROR_PROCEDURE] [nvarchar](maks.) 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] KLUCZ PODSTAWOWY ([ErrorInfo_GUID] ASC) Z (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 TABELA R [srv]. [ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ErrorInfoArchive_ErrorInfo_GUID] DOMYŚLNE (newsectionid()) DLA [ErrorInfo_GUID]TABELI GOALTERÓW [srv].[ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ArchiveErrorInfo_GUID] (NERRORGATEERT) TABLES DEFATED [srv].[ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ErrorInfoArchive_StartDate] DOMYŚLNE (getdate()) DLA [Data początkowa]TABELI BRAMKARÓW [srv].[ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ErrorInfoArchive_FinishDate] DEFAULTrGOALTERFigetDTABLE [srv].[ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ErrorInfoArchive_FinishDate] ].[ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ErrorInfoArchive_Count] DOMYŚLNE ((1)) DLA [Count]TABELA BRAMKARÓW [srv].[ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ErrorInfoArchive_UpdateDate] DOMYŚLNE (getdate()) DLA [UpdateDate]GOAL [ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ErrorInfoArchive_IsRealTime] DOMYŚLNE ((0)) DLA [IsRealTime] TABELI BRAMKARÓW [srv]. [ErrorInfoArchive] DODAJ OGRANICZENIE [DF_ErrorInfoArchive_InsertUTCDate] DOMYŚLNE (CD)pIngotcdate()) ponownie> 

[/expand]

Te informacje są potrzebne do tworzenia historii. Poza tym ta tabela musi zostać usunięta z bardzo starych danych (na przykład starszych niż miesiąc).

6. Utwórz procedurę składowaną, która rejestruje nową wiadomość w kolejce wiadomości:

[rozwiń tytuł ="Kod"]

UŻYJ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[ErrorInfoIncUpd] @ERROR_TITLE nvarchar(max), @ERROR_PRED_MESSAGE nvarchar(max), @varAGEROROR_max ), @varAGERROR_LINE nvarchar(max), @ERROR_PROCEDURE nvarchar(max), @ERROR_POST_MESSAGE nvarchar(max), @RECIPIENTS nvarchar(max), @StartDate datetime=null, @FinishDate datetime=null, @IsRealTime bit =0ASBEGIN /* Błąd podczas logowania tabela do wysłania e-mailem, jeśli w tabeli jest już wpis o tym samym tytule, treści i nadawcy, zmieni się data zakończenia błędu, data aktualizacji rekordu oraz liczba błędów */ USTAW NR. NA; zadeklaruj unikalny identyfikator @ErrorInfo_GUID; wybierz top 1 @ErrorInfo_GUID=ErrorInfo_GUID z srv.ErrorInfo gdzie ([email protected]_TITLE lub @ERROR_TITLE ma wartość null) i [email protected] i ([email protected]_MESSAGE lub @ERROR_MESSAGE ma wartość null) i (przykład@sqldat_AGE_s) lub @ERROR_PRED_MESSAGE ma wartość null) i ([email protected]_POST_MESSAGE lub @ERROR_POST_MESSAGE ma wartość null) i ([email protected] lub @IsRealTime ma wartość null); if (@ERRORINFO_GUID IS NULL) Rozpocznij wstaw do srv.errorinfo (błąd_title, error_pred_message, error_number, error_message, error_line, error_procedure, error_post_message, odbiorcy, isrealtime, steralDate, FinansDate) Wybierz @error_title,@error_pred_message, error_number, error_numer, error_number, error_message, ERROR_LINE ,@ERROR_PROCEDURE ,@ERROR_POST_MESSAGE ,@RECIPIENTS ,@IsRealTime ,isnull(@StartDate, getdate()) ,isnull(@FinishDate,getdate()) end else rozpocznij aktualizację srv.ErrorInfo set FinishDate=getdate(), [Count]=[Count]+1, UpdateDate=getdate() gdzie [email protected]_GUID; koniecENDGO

[/expand]

7. Utwórz procedurę składowaną, która zwraca ciąg z adresów według kodu lub podstawowego adresu e-mail odbiorcy:

[rozwiń tytuł ="Kod"]

UŻYJ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER PROCEDURA ONGOCREATE [srv].[GetRecipients]@Nazwa_odbiorcy nvarchar(255)=NULL,@Kod_odbiorcy nvarchar(10)=NULL,@zmienna*Procedura(max) n tworzenie powiadomień e-mail*/ASBEGIN SET NOCOUNT ON; ustaw @Odbiorcy=''; wybierz @[email protected]+d.[Adres]+';' from srv.Recipient jako r inner join srv.[Adres] jako d na r.Recipient_GUID=d.Recipient_GUID gdzie (przykł[email protected]_Name lub @Recipient_Name JEST NULL) i (przykł[email protected]_Code lub @Recipient_Code JEST NULL) oraz r.IsDeleted=0 i 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. Utwórz niezbędne funkcje do pracy z datami i godzinami:

[rozwiń tytuł ="Kod"]

UŻYJ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [rep].[GetDateFormat] ( @dt datetime, // data wejściowa @format int=0 // ustawiony format) ZWRACA nvarchar(255)AS/* Zwraca datę jako ciąg znaków zgodnie z podanym formatem i datą wejścia W razie potrzeby wstawia zera:format data wejścia wynik 0 17.4.2014 "17.04.2014" 1 17.4.2014 "04.2014" 1 8.11.2014 "11.2014" 2 17.04.2014 "2014" */POCZĄTEK ZGŁOSZENIA @res nvarchar(255); ZADEKLARUJ @dzień int=DZIEŃ(@dt); ZADEKLARUJ @miesiąc int=MIESIĄC(@dt); ZADEKLARUJ @rok int=ROK(@dt); if(@format=0) rozpocznij ustaw @res=IIF(@day<10,'0'+cast(@day as nvarchar(1)), cast(@day as nvarchar(2)))+'.'; set @[email protected]+IIF(@miesiąc<10,'0'+cast(@miesiąc jako nvarchar(1)), rzut(@miesiąc jako nvarchar(2)))+'.'; ustaw @[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)))+'. '; ustaw @[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, // input time @format int=0 // preset format)RETURNS nvarchar(255)AS/* Zwraca czas jako ciąg zgodnie z podanym formatem i czasem wejścia Wstawia zera tam, gdzie to konieczne:format czasu wejścia wynik 0 17:04 "17:04:00" 1 17:04 "17:04" 1 8:04 "08:04 " 2 17:04 "17"*/POCZĄTEK ZGŁOSZENIA @res nvarchar(255); ZADEKLARUJ @godzina int=DATACZĘŚĆ(GODZINA, @dt); ZADEKLARUJ @min int=DATACZĘŚĆ(MINUTA, @dt); ZADEKLARUJ @sec int=DATACZĘŚĆ(DRUGA, @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 jako nvarchar(1)), rzut(@min jako nvarchar(2)))+':'; ustaw @[email protected]+IIF(@sec<10,'0'+cast(@sec jako nvarchar(1)), cast(@sec jako nvarchar(2))); end else if(@format=1) begin set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2)))+':'; ustaw @[email protected]+IIF(@min<10,'0'+cast(@min jako nvarchar(1)), cast(@min jako nvarchar(2))); end else if(@format=2) begin set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2))); koniec RETURN @res;ENDGO

[/expand]

9. Utwórz procedurę składowaną, która tworzy raport HTML dotyczący wiadomości w formie tabeli:

[rozwiń tytuł ="Kod"]

UŻYJ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetHTMLTable] @recipients nvarchar(max) ,@dt datetime // do której daty czytać ASBEGIN /* generuje kod HTML dla tabeli */ SET NOCOUNT ON; zadeklaruj @body nvarchar(max); zadeklaruj @tbl table(ID int identity (1,1) ,[ERROR_TITLE] nvarchar(max) ,[ERROR_PRED_MESSAGE] nvarchar(max) ,[ERROR_NUMBER] nvarchar(max) ,[ERROR_MESSAGE] nvarchar(max) ,[nvarchar_LINE] (max) ,[ERROR_PROCEDURE] nvarchar(max) ,[ERROR_POST_MESSAGE] nvarchar(max) ,[InsertDate] datetime ,[StartDate] datetime ,[FinishDate] datetime ,[Count] int ); zadeklaruj @ID int ,@ERROR_TITLE nvarchar(max) ,@ERROR_PRED_MESSAGE nvarchar(max) ,@ERROR_NUMBER nvarchar(max) ,@ERROR_MESSAGE nvarchar(max) ,@ERROR_LINE nvarchar(MESSAGE) nvarchar(max) (maks.) ,@InsertDate datetime ,@StartDate datetime ,@FinishDate datetime ,@Count int wstaw do @tbl( [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERRORERRESSORAGE]_PRO,[COS ] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] ) wybierz pierwszą setkę [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] from [srv].[ErrorInfo], gdzie ([@RECIQlDAT].com ) lub (@recipients IS NULL) i InsertDate'; ustaw @[email protected]+''; ustaw @[email protected]+'№ п/п'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'DATA'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'BŁĄD'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'OPIS'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'KOD BŁĘDU'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'WIADOMOŚĆ'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'START'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'FINISH'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'LICZBA'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'NUMER LINII'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'PROCEDURA'; ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+'UWAGA'; ustaw @[email protected]+''; ustaw @[email protected]+''; while((wybierz top 1 1 z @tbl)>0) rozpocznij set @[email protected]+''; wybierz top 1 @ID =[ID] ,@ERROR_TITLE =[ERROR_TITLE] ,@ERROR_PRED_MESSAGE=[ERROR_PRED_MESSAGE] ,@ERROR_NUMBER =[ERROR_NUMBER] ,@ERROR_MESSAGE =[ERROR_MESSAGE]_PROEDRORCELL =[ERROR_MESSAGE] =[ERROR_LINE] ] ,@ERROR_POST_MESSAGE=[ERROR_POST_MESSAGE] ,@InsertDate =[InsertDate] ,@StartDate =[StartDate] ,@FinishDate =[FinishDate] ,@Count =[Liczba] z @tbl zamówienia według daty wstawienia asc; ustaw @[email protected]+''; ustaw @[email protected]+cast(@ID jako nvarchar(max)); ustaw @[email protected]+''; ustaw @[email protected]+''; set @[email protected]+rep.GetDateFormat(@InsertDate, domyślnie)+' '+rep.GetTimeFormat(@InsertDate, domyślnie); // cast(@InsertDate as nvarchar(max)); ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+isnull(@ERROR_TITLE,''); ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+isnull(@ERROR_PRED_MESSAGE,''); ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+isnull(@ERROR_NUMBER,''); ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+isnull(@KOMUNIKAT_BŁĘDU,''); ustaw @[email protected]+''; ustaw @[email protected]+''; set @[email protected]+rep.GetDateFormat(@StartDate, default)+' '+rep.GetTimeFormat(@StartDate, default); //cast(@DataRozpoczęcia jako nvarchar(max)); ustaw @[email protected]+''; ustaw @[email protected]+''; set @[email protected]+rep.GetDateFormat(@FinishDate, domyślnie)+' '+rep.GetTimeFormat(@FinishDate, default); //cast(@DataZakończenia jako nvarchar(max)); ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+cast(@Count as nvarchar(max)); ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+isnull(@ERROR_LINE,''); ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+isnull(@ERROR_PROCEDURE,''); ustaw @[email protected]+''; ustaw @[email protected]+''; ustaw @[email protected]+isnull(@ERROR_POST_MESSAGE,''); ustaw @[email protected]+''; usuń z @tbl gdzie [email protected]; ustaw @[email protected]+''; koniec zestawu @[email protected]+''; wybierz @body;ENDGO

[/expand]

10. Utwórz procedurę składowaną, która wysyła wiadomości:

[rozwiń tytuł ="Kod"]

USE [DATABAE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[RunErrorInfoProc] @IsRealTime bit =0 // tryb wysyłania (1-w czasie rzeczywistym)ASBEGIN /* wysyłanie powiadomień o błędach w określonym trybie */ SET NOCOUNT ON; zadeklaruj @dt datetime=getdate(); zadeklaruj @tbl table(Odbiorcy nvarchar(max)); zadeklaruj @odbiorcy nvarchar(max); zadeklaruj @ odbiorca nvarchar(255); zadeklaruj @result nvarchar(max)=''; zadeklaruj @recp nvarchar(max); zadeklaruj @ind int; zadeklaruj @recipients_key nvarchar(max); // odbierz wszystkie potrzebne wiadomości wstaw do @tbl(Odbiorcy) wybierz [ODBIORCY] z srv.ErrorInfo gdzie InsertDate0) begin //odbierz odbiorców select top (1) @recipients=Recipients from @tbl; ustaw @[email protected]; ustaw @wynik=''; // dla każdego odbiorcy 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]); koniec inny początek ustaw @[email protected]; ustaw @odbiorcy=''; koniec; // odbierz e-maile od odbiorców 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) ustaw @[email protected]; koniec // oddzielone symbolem ';' ustaw @[email protected]@sqldat.com+';'; end set @result=substring(@result,1,len(@result)-1); ustaw @[email protected]; // odbierz raport HTML z określonymi odbiorcami i datą wstaw do @rec_body(Body) exec srv.GetHTMLTable @[email protected]_key, @[email protected]; // odbierz raport HTML select top (1) @body=Body from @rec_body; // rzeczywisty wysyłający EXEC msdb.dbo.sp_send_dbmail // e-mailowy profil administratora, który utworzyliśmy @profile_name ='ALARM', //e-mail odbiorcy @recipients =@recipients, // tekst wiadomości @body =@body, // Temat @subject =N'INFORMACJE O BŁĘDACH WYKONANIA', @body_format='HTML'--, // Na przykład dodajmy wyniki losowego zapytania SQL do wiadomości [email protected] =@query--'SELECT TOP 10 nazwa Z sys.objects'; usuń z @tbl gdzie [email protected]_key; usuń z @rec_body; zakończ // zarchiwizuj wysłane wiadomości INSERT INTO [srv].[ErrorInfoArchive] ([ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[CESSROR_AGE] ODBIORCY] ,[DataRozpoczęcia] ,[DataZakończenia] ,[Liczba] ,IsRealTime ) SELECT [ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_MESSAGE] ,[ERROR],[ERROR_MESSAGE] [ODBIORCY] ,[DataRozpoczęcia] ,[DataZakończenia] ,[Liczba] ,IsRealTime FROM [srv].[ErrorInfo] gdzie [email protected] i InsertDate 

[/expand]

Ta procedura składowana pobiera każdą wiadomość z kolejki wiadomości i umieszcza ją w raporcie HTML w formie tabeli. Dla odbiorców, na podstawie ich kodu lub podstawowego adresu e-mail, tworzy ciąg składający się z adresów e-mail, na które wysyłana jest wiadomość. W ten sposób przetwarzane są wszystkie wybrane wiadomości. Tutaj używana jest procedura składowana msdb.dbo.sp_send_dbmail.

11. Utwórz dwa zadania w Agencie (pierwsze dla powiadomień w czasie rzeczywistym (zaplanuj 1 raz na minutę), drugie dla prostych powiadomień (zaplanuj 1 raz na godzinę)). Dodaj następujące elementy do kodu zadania:

WYKONAJ [NAZWA_BAZY_DANYCH].[srv].[RunErrorInfoProc] @IsRealTime=0; // 0 - dla prostych wiadomości i 1 - dla wiadomości w czasie rzeczywistym

Oto przykład zgłaszania błędów:

[rozwiń tytuł=”Kod”]

rozpocznij wykonywanie exec [NAZWA_BAZY_DANYCH].[srv].[KillFullOldConnect];zakończ trybegin catch zadeklaruj @str_mess nvarchar(max)=KOMUNIKAT_BŁĘDU(), @str_num nvarchar(max)=cast(NUMER_BŁĘDU() jako nvarchar(max) ), @str_line nvarchar(max)=cast(ERROR_LINE() as nvarchar(max)), @str_proc nvarchar(max)=ERROR_PROCEDURE(), @str_title nvarchar(max)='USUWANIE PROCESÓW NIE ODPOWIADAJĄCYCH NA SERWERZE'przykład @sqldat.com@nazwa_serwera, @str_pred_mess nvarchar(max)='BŁĄD USUNIĘCIA PROCESÓW NIE ODPOWIADAJĄCYCH NA SERWERZE '[email protected]@nazwa_serwera+'; 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 =@ROR_PRED_MESSAGE=ODBIORCY ='ODBIORCA1;ODBIORCA2'; zadeklaruj @err [email protected]@error; raiserror(@str_mess,16,1);zatrzask końcowy

[/expand]

Tutaj używana jest procedura składowana svr.KillFullOldConnect.

Wynik

Ten artykuł zawiera przykład rozszerzenia funkcjonalności zwykłej poczty bazy danych oraz przykład generowania powiadomień w tabelach HTML, a następnie wysyłania ich pocztą elektroniczną do administratorów. Takie podejście umożliwia powiadamianie administratorów o różnych problemach w czasie rzeczywistym lub po określonym czasie, minimalizując w ten sposób wystąpienie krytycznego problemu i awarii DBMS i serwera, co z kolei chroni produkcję przed opóźnieniami w przepływie pracy.

Odniesienia:

  1. Sp_send_dbmail
  2. Poczta bazy danych
  3. Srv.KillFullOldConnect

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server ROWCOUNT_BIG()

  2. Odwołaj się do aliasu w innym miejscu na liście WYBIERZ

  3. Zapytanie SQL „LIKE” przy użyciu „%”, gdzie kryteria wyszukiwania zawierają „%”

  4. Wybierz / wstaw wersję Upsert:czy istnieje wzorzec projektowy dla wysokiej współbieżności?

  5. 3 sposoby zwracania wierszy zawierających znaki alfanumeryczne w SQL Server