Úvod
Často je potřeba nějak informovat administrátory o problémech se serverem. Oznámení se obecně dělí na 2 typy:
1) upozornění v reálném čase, tedy taková, která musí přijít okamžitě, když dojde k problému
2) zpožděná upozornění, tj. taková, která přijdou po poměrně dlouhé době (více než 1 hodina) po výskytu problému.
V mé práci bylo nutné rozšířit funkčnost běžné SQL Server Database Mail.
V tomto článku se podíváme na příklad, jak generovat oznámení v tabulkách HTML a poté je odesílat správcům.
Řešení
1. Konfigurace pošty databáze
2. Vytvořte tabulku pro příjemce:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Recipient]( [Recipient_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL, [Recipient_Name] [nvarchar] (255 primární e-mail příjemce) (255) Recipient_Code] [nvarchar](10) NOT NULL, // kód příjemce [IsDeleted] [bit] NOT NULL, // indikátor smazání (zda je příjemce použit nebo ne) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Recipient ] PRIMARY KEY CLUSTERED ( [Recipient_GUID] ASC)WITH (PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO (PAD_INDEX =VYPNUTO, Co (PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMARY], OMEZENO [AK_Recipient_Name] JEDINEČNÝ =NEZAHRNUTÝ STATIST_INDEXU ([PŘÍJEMCE] VYPNUTÝ STATISTICKÝ PŘÍJEMCE) F, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMÁRNÍ]) NA [PRIMÁRNÍ] BRANKÁŘSKÉ TABULCE [srv].[Příjemce] PŘIDAT OMEZENÍ [DF_Recipient_Recipient_GUID] VÝCHOZÍ ID GOAL (newTERsequensequent) srv].[Recipient] PŘIDAT OMEZENÍ [DF_Recipient_IsDeleted] VÝCHOZÍ ((0)) PRO [IsDeleted]TABULKA BRANKA [srv].[Recipient] PŘIDAT OMEZENÍ [DF_Recipient_InsertUTCDate] VÝCHOZÍ (getutcdate()) PRO [InsertpreUTCDate][/expand]
3. Vytvořte tabulku pro adresy příjemců:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Adresa]( [Address_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL, [Recipient_GUID] [uniqueidentifier] [Uniqueidentifier] // příjemce NOT NULL, 255) NOT NULL, // e-mail [IsDeleted] [bit] NOT NULL, // indikátor smazání (ať už je e-mail použit nebo ne) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Address] PRIMÁRNÍ KLÍČ SE SLUSTROVANÝ ( [Address_GUID] ASC )WITH (PAD_INDEX =VYPNUTO, STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMÁRNÍ], OMEZENÍ [AK_Adresa] JEDINEČNÁ [AK_Adresa] JEDINEČNÁ ADRESA, NEZAHRNUTÉ_Adresa WISC] VYP. , STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMARY]) NA [PRIMARY]TABULKA BRANKA [srv].[Adresa] PŘIDAT OMEZENÍ (ID_GUULT_GUID) FOR Adresa BRANKÁŘSKÁ TABULKA [ srv].[Adresa] PŘIDAT OMEZENÍ [DF_Address_IsDeleted] VÝCHOZÍ ((0)) PRO [IsDeleted]TABULKA BRANKA [srv].[Address] PŘIDAT OMEZENÍ [DF_Address_InsertUTCDate] VÝCHOZÍ (getutcdate()) PRO [InsertUTCDate]PŘEJÍT[/expand]
4. Vytvořte tabulku pro frontu zpráv:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfo]( [ErrorInfo_GUID] [uniqueidentifier] NENÍ NULL, [ERROR_TITLE] [nvarchar](max) [nvarchar] [NERvarPchar] //AGE (max) NULL, // předběžné informace [ERROR_NUMBER] [nvarchar](max) NULL, // kód zprávy (chyby) [ERROR_MESSAGE] [nvarchar](max) NULL, // zpráva [ERROR_LINE] [nvarchar](max) NULL, // číslo řádku [ERROR_PROCEDURE] [nvarchar](max) NULL, // uložená procedura [ERROR_POST_MESSAGE] [nvarchar](max) NULL, // vysvětlující informace [RECIPIENTS] [nvarchar](max) NULL, // příjemce odděleno ';' [InsertDate] [datetime] NOT NULL, [StartDate] [datetime] NOT NULL, // počáteční data a čas [FinishDate] [datetime] NOT NULL, // datum a čas ukončení [Count] [int] NOT NULL, // kolikrát [UpdateDate] [dat etime] NOT NULL, [IsRealTime] [bit] NOT NULL, // indikátor reálného času [InsertUTCDate] [datetime] NULL, CONSTRAINT [PK_ErrorInfo] PRIMÁRNÍ KLÍČ SE SLUSTROVANÝ ( [ErrorInfo_GUID] ASC)WITH (PAD_INDEX =OFF_NORETE STATICISTICS IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMÁRNÍ]) NA [PRIMÁRNÍ] TEXTIMAGE_ON [PRIMARY]BRANKÁŘSKÁ TABULKA [srv].[ErrorInfo] PŘIDAT OMEZENÍ [DF_ErridorInfo))FORFAELD TABLE [srv].[ErrorInfo] PŘIDAT OMEZENÍ [DF_ErrorInfo_InsertDate] VÝCHOZÍ (getdate()) PRO [InsertDate]TABULKA BRANKA [srv].[ErrorInfo] PŘIDAT OMEZENÍ [DF_ErrorInfo_StartDate] VÝCHOZÍ [getDate()TER)VÝCHOZÍ [getDate()TER)VÝCHOZÍ [getDate()TER)TABLE] srv].[ErrorInfo] PŘIDAT OMEZENÍ [DF_ErrorInfo_FinishDate] VÝCHOZÍ (getdate()) PRO [FinishDate]TABULKA BRANKŮ [srv].[ErrorInfo] PŘIDAT OMEZENÍ [DF_ErrorInfo_Count] VÝCHOZÍ ((1)) PRO [POČET]GOALrv [ErrorInfo] PŘIDAT OMEZENÍ [DF__ErrorInfo__Updat__5FFEE747] DEFAU LT (getdate()) PRO [UpdateDate]TABULKA BRANKA [srv].[ErrorInfo] PŘIDAT OMEZENÍ [DF_ErrorInfo_IsRealTime] VÝCHOZÍ ((0)) PRO [IsRealTime]TABULKA BRANKA [srv].[ErrorInfo] PŘIDAT OMEZENÍ [DF_InsERrInFAULT] DEFAULT getutcdate()) PRO [InsertUTCDate]PŘEJÍT[/expand]
5. Vytvořte archivní tabulku pro zprávy odeslané z fronty zpráv:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfoArchive]( [ErrorInfo_GUID] [jednoznačný identifikátor] ROWGUIDCOL NENÍ NULL, [ERROR_TITLE] [ERROR_TITLE] [ERROR_TITLE] [ERRESS(e)char]OR max. ) NULL, [ERROR_NUMBER] [nvarchar](max) NULL, [ERROR_MESSAGE] [nvarchar](max) NULL, [ERROR_LINE] [nvarchar](max) NULL, [ERROR_PROCEDURE] [nvarchar](max) NULL, [ERESSROR_POST_MAGE [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] PRIMÁRNÍ KLÍČ SE SLUSTROVANÝ ( [ErrorInfo_GUID] ASC_INDEX =PADEX) STATISTICS_NORECOMPUTE =VYPNUTO, IGNORE_DUP_KEY =VYPNUTO, ALLOW_ROW_LOCKS =ZAPNUTO, ALLOW_PAGE_LOCKS =ZAPNUTO) ZAPNUTO [PRIMARY]) ZAPNUTO [PRIMARY] TEXTIMAGE_ON [PRIMARY]GOALTE R TABULKA [srv].[ErrorInfoArchive] PŘIDAT OMEZENÍ [DF_ErrorInfoArchive_ErrorInfo_GUID] VÝCHOZÍ (newsequentialid()) PRO [ErrorInfo_GUID]TABULKA BRANKÁŘE [srv].[ErrorInfoArchive] PŘIDAT OMEZENÍ]DATUM GOALFAEDFs_BLEHTA [srv].[ErrorInfoArchive] PŘIDAT OMEZENÍ [DF_ErrorInfoArchive_StartDate] VÝCHOZÍ (getdate()) PRO [StartDate]TABULKA BRANKŮ [srv].[ErrorInfoArchive] PŘIDAT OMEZENÍ [DF_ErrorInfoArchive_FinishDate]FORrvDate]TERFAULT (getdate)GOrvDate]TERFAULT ].[ErrorInfoArchive] PŘIDAT OMEZENÍ [DF_ErrorInfoArchive_Count] VÝCHOZÍ ((1)) PRO [Count]TABULKA BRANKŮ [srv].[ErrorInfoArchive] PŘIDAT OMEZENÍ [DF_ErrorInfoArchive_UpdateDate] VÝCHOZÍ [GetUpdate]GOALTER) VÝCHOZÍ [getUpdate]. [ErrorInfoArchive] PŘIDAT OMEZENÍ [DF_ErrorInfoArchive_IsRealTime] VÝCHOZÍ ((0)) PRO [IsRealTime]TABULKA BRANKŮ [srv].[ErrorInfoArchive] PŘIDAT OMEZENÍ [DF_ErrorInfoArchive_InsertUTCDate] FORMULÁŘ] DEFAULT[/expand]
Tyto informace jsou potřebné pro historii. Kromě toho je potřeba tuto tabulku vymazat z velmi starých dat (například starších než jeden měsíc).
6. Vytvořte uloženou proceduru, která zaregistruje novou zprávu do fronty zpráv:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER POSTUP PŘI VYTVOŘENÍ [srv].[ErrorInfoIncUpd] @ERROR_TITLE nvarchar(max), @ERROR_PRED_MESSAGE nvarchar(max), charAGEERnOR_NUMBER(max), charAGEERnORLINENUMBER(max),charager nvarchar(max), @ERROR_PROCEDURE nvarchar(max), @ERROR_POST_MESSAGE nvarchar(max), @RECIPIENTS nvarchar(max), @StartDate datetime=null, @FinishDate datetime=null, @IsRealTime bit =0ASBEGIN /* Chyba nebo přihlášení tabulka k odeslání e-mailem, pokud tabulka již obsahuje záznam se stejným názvem, obsahem a odesílatelem, změní se datum ukončení chyby, datum aktualizace záznamu a také počet chyb */ SET NOCOUNT NA; deklarovat jedinečný identifikátor @ErrorInfo_GUID; vyberte top 1 @ErrorInfo_GUID=ErrorInfo_GUID z srv.ErrorInfo, kde ([email protected]_TITLE nebo @ERROR_TITLE je null) a [email protected] a ([email protected]_MESSAGE nebo @ERROR_MESSAGE_lqRED_MESSAGE je null. a nebo @ERROR_PRED_MESSAGE je null) a ([email protected]_POST_MESSAGE nebo @ERROR_POST_MESSAGE je null) a ([email protected] nebo @IsRealTime je null); 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; endENDGO[/expand]
7. Vytvořte uloženou proceduru, která vrátí řetězec z adres podle kódu nebo primární e-mailové adresy příjemce:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER VYTVOŘENÝ POSTUP [srv].[GetRecipients]@Recipient_Name nvarchar(255)=NULL,@Recipient_Code nvarchar(10)=Procedura NULL,/*Recipient vytváření e-mailových upozornění*/ASBEGIN SET NOCOUNT ON; set @Recipients=''; vyberte @[email protected]+d.[Adresa]+';' z srv.Recipient jako r vnitřní spojení srv.[Adresa] jako d na r.Recipient_GUID=d.Recipient_GUID kde ([email protected]_Name nebo @Recipient_Name JE NULL) a ([email protected]_Code nebo @Recipient_Code JE NULL) a r.IsDeleted=0 a d.IsDeleted=0; --řazení podle r.InsertUTCDate desc, d.InsertUTCDate desc; if(len(@Recipients)>0) set @Recipients=substring(@Recipients,1,len(@Recipients)-1);ENDGO[/expand]
8. Vytvořte potřebné funkce pro práci s daty a časem:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [rep].[GetDateFormat] ( @dt datetime, // zadání data @format int=0 // přednastavený formát)VRÁTÍ nvarchar(255)AS/* Vrátí datum řetězec podle zadaného formátu a vstupního data V případě potřeby vloží nuly:formát zadání data výsledek 0 17.4.2014 "17.04.2014" 1 17.4.2014 "04.2014" 1 8.11.2014 "11.2014" 2 17.4.04. */BEGIN DECLARE @res nvarchar(255); DECLARE @day int=DAY(@dt); DECLARE @month int=MONTH(@dt); DECLARE @year int=YEAR(@dt); if(@format=0) begin set @res=IIF(@den<10,'0'+cast(@den jako nvarchar(1)), cast(@den jako nvarchar(2)))+'.'; set @[email protected]+IIF(@měsíc<10,'0'+cast(@měsíc jako nvarchar(1)), obsazení(@měsíc jako nvarchar(2)))+'.'; nastavit @[email protected]+cast(@rok jako nvarchar(255)); end else if(@format=1) begin set @res=IIF(@měsíc<10,'0'+cast(@měsíc jako nvarchar(1)), obsazení(@měsíc jako nvarchar(2)))+'. '; nastavit @[email protected]+cast(@rok jako 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, // vstupní čas @format int=0 // návratový formát)RETURNS nvarchar(255)AS čas jako řetězec podle zadaného formátu a vstupního času V případě potřeby vloží nuly:formát zadání času výsledek 0 17:04 "17:04:00" 1 17:04 "17:04" 1 8:04 "08:04 " 2 17:04 "17"*/ZAČÁTEK DECLARE @res nvarchar(255); DECLARE @hour int=DATEPART(HOUR, @dt); DECLARE @min int=DATEPART(MINUTE, @dt); DECLARE @sec int=DATEPART(SECOND, @dt); if(@format=0) begin set @res=IIF(@hodina<10,'0'+cast(@hodina jako nvarchar(1)), cast(@hodina jako nvarchar(2)))+':'; set @[email protected]+IIF(@min<10,'0'+cast(@min jako nvarchar(1)), cast(@min jako nvarchar(2)))+':'; set @[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(@hodina<10,'0'+cast(@hodina jako nvarchar(1)), cast(@hodina jako nvarchar(2)))+':'; set @[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(@hodina<10,'0'+cast(@hodina jako nvarchar(1)), cast(@hodina jako nvarchar(2))); end RETURN @res;ENDGO[/expand]
9. Vytvořte uloženou proceduru, která vytvoří zprávu HTML o zprávách ve formě tabulky:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetHTMLTable] @recipients nvarchar(max) ,@dt datetime // do kterého data čístASBEGIN /* vygeneruje HTML kód pro tabulku */ SET NOCOUNT ON; deklarovat @body nvarchar(max); deklarovat tabulku @tbl(ID int identity(1,1) ,[ERROR_TITLE] nvarchar(max) ,[ERROR_PRED_MESSAGE] nvarchar(max) ,[ERROR_NUMBER] nvarchar(max) ,[ERROR_MESSAGE] nvarchar(max) ,[ERROR_LINE] n (max) ,[ERROR_PROCEDURE] nvarchar(max) ,[ERROR_POST_MESSAGE] nvarchar(max) ,[InsertDate] datetime ,[StartDate] datetime ,[FinishDate] datetime ,[Count] int ); deklarovat @ID int ,@ERROR_TITLE nvarchar(max) ,@ERROR_PRED_MESSAGE nvarchar(max) ,@ERROR_NUMBER nvarchar(max) ,@ERROR_MESSAGE nvarchar(max) ,@ERROR_LINE nvarchar(max) ,@ESSERRAGEnvar_PROChar_PROCARER (max) ,@InsertDate datetime ,@StartDate datetime ,@FinishDate datetime ,@Count int vložení do @tbl( [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERRORESSRORURE_LINE],_PRODUKCE] ] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] ) vybrat 100 nejlepších [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] ,[InsertDate] ,[Datum zahájení] ,[Datum dokončení] ,[Počet] z [srv].[ErrorInfo] kde ([example.com@s] ) nebo (@recipients IS NULL) a InsertDate'; set @example@sqldat.com+' '; set @[email protected]+' '; while((vyberte top 1 1 z @tbl)>0) begin set @[email protected]+''; set @[email protected]+'№ п/п'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'DATUM'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'ERROR'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'DESCRIPTION'; set @[email protected]+' '; set @[email protected]+''; nastavit @[email protected]+'KÓD CHYBY'; 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]+''; nastavit @[email protected]+'ČÍSLO'; set @[email protected]+' '; set @[email protected]+''; nastavit @[email protected]+'ČÍSLO ŘÁDKU'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'PROCEDURE'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'POZNÁMKA'; set @[email protected]+' '; set @[email protected]+''; vybrat top 1 @ID =[ID] ,@ERROR_TITLE =[ERROR_TITLE] ,@ERROR_PRED_MESSAGE=[ERROR_PRED_MESSAGE] ,@ERROR_NUMBER =[ERROR_NUMBER] ,@ERROR_MESSAGE =[ERROR_MESSAGE] ,@ERROR_PRED_LINECERR =[ERROR_LINECERERR =[ERROR_LINEC ] ,@ERROR_POST_MESSAGE=[ERROR_POST_MESSAGE] ,@InsertDate =[Datum vložení] ,@Datum zahájení =[Datum zahájení] ,@Datum dokončení =[Datum dokončení] ,@Počet =[Počet] z objednávky @tbl podle Datum vložení asc; set @[email protected]+' '; koncová sada @[email protected]+''; vyberte @body;ENDGO'; nastavit @[email protected]+cast(@ID jako nvarchar(max)); set @[email protected]+' '; set @[email protected]+''; set @[email protected]+rep.GetDateFormat(@InsertDate, výchozí)+' '+rep.GetTimeFormat(@InsertDate, výchozí); // 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, default)+' '+rep.GetTimeFormat(@StartDate, default); //cast(@StartDate as nvarchar(max)); set @[email protected]+' '; set @[email protected]+''; set @[email protected]+rep.GetDateFormat(@FinishDate, default)+' '+rep.GetTimeFormat(@FinishDate, default); //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]+' '; odstranit z @tbl kde [email protected]; set @[email protected]+'[/expand]
10. Vytvořte uloženou proceduru, která odesílá zprávy:
[rozbalit název =”Kód”]
POUŽÍVEJTE [DATABAE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[RunErrorInfoProc] @IsRealTime bit =0 // režim odesílání (1 v reálném čase) ASBEGIN /* odesílání chybových oznámení se zadaným režimem */ SET NOCOUNT ON; deklarovat @dt datetime=getdate(); deklarovat @tbl tabulku(Příjemci nvarchar(max)); deklarovat @recipients nvarchar(max); deklarovat @recipient nvarchar(255); deklarovat @výsledek nvarchar(max)=''; deklarovat @recp nvarchar(max); deklarovat @ind int; deklarovat @recipients_key nvarchar(max); // přijme všechny potřebné zprávy vložte do @tbl(Příjemci) vyberte [RECIPIENTS] z srv.ErrorInfo kde InsertDate0) begin //příjem příjemců vybrat top (1) @recipients=Příjemci z @tbl; set @[email protected]; set @vysledek=''; // pro každého příjemce while(len(@příjemci)>0) begin set @ind=CHARINDEX(';', @příjemci); 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=''; konec; // příjem e-mailů příjemců 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 // oddělené symbolem ';' set @[email protected]@sqldat.com+';'; end set @výsledek=podřetězec(@výsledek,1,délka(@výsledek)-1); set @[email protected]; // přijme HTML-report se zadanými příjemci a datem vloženým do @rec_body(Body) exec srv.GetHTMLTable @[email protected]_key, @[email protected]; // příjem zprávy HTML select top (1) @body=Body from @rec_body; // skutečné odeslání EXEC msdb.dbo.sp_send_dbmail // emailový profil administrátora, který jsme vytvořili @profile_name ='ALARM', //e-mail příjemce @recipients =@recipients, // text zprávy @body =@body, // Předmět @subject =N'INFORMACE O CHYBÁCH PROVEDENÍ', @body_format='HTML'--, // Přidejme například výsledky náhodného SQL dotazu do zprávy [email protected] =@query--'SELECT TOP 10 název FROM sys.objects'; odstranit z @tbl kde [email protected]_key; smazat z @rec_body; end // archivace odeslaných zpráv INSERT INTO [srv].[ErrorInfoArchive] ([ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERRORER_LINE] ,[EDRESSORAGE]PRO RECIPIENTS] ,[Datum zahájení] ,[Datum ukončení] ,[Počet] ,IsRealTime ) VYBERTE [ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERRERROR_MESSOR_LINE] ,[OSTRORER] ,[AGERRER] ,[AGERRER] [RECIPIENTS] ,[Datum zahájení] ,[Datum dokončení] ,[Počet] ,IsRealTime FROM [srv].[Info o chybě] kde [email protected] a InsertDate [/expand]
Tato uložená procedura převezme každou zprávu z fronty zpráv a zabalí ji do zprávy HTML ve formě tabulky. Pro příjemce na základě jejich kódu nebo primární emailové adresy vytvoří řetězec složený z emailových adres, na který je odeslána zpráva. Tímto způsobem jsou zpracovány všechny vybrané zprávy. Zde se používá uložená procedura msdb.dbo.sp_send_dbmail.
11. Vytvořte dvě úlohy v Agentovi (první je pro upozornění v reálném čase (plán 1krát za minutu), druhá je pro jednoduchá upozornění (plán 1krát za hodinu)). Přidejte do kódu úlohy následující:
PROVEĎTE [DATABASE_NAME].[srv].[RunErrorInfoProc] @IsRealTime=0; // 0 - pro jednoduché zprávy a 1 - pro zprávy v reálném časeZde je příklad hlášení chyb:
[expand title=”Kód”]
začněte zkusit exec [DATABASE_NAME].[srv].[KillFullOldConnect];end trybegin catch deklarujte @str_mess nvarchar(max)=ERROR_MESSAGE(), @str_num nvarchar(max)=cast(ERROR_NUMBER() jako nvarchar(max) ), @str_line nvarchar(max)=cast(ERROR_LINE() jako nvarchar(max)), @str_proc nvarchar(max)=ERROR_PROCEDURE(), @str_title nvarchar(max)='VYMAZÁNÍ NEODPOVÍDAJÍCÍCH PROCESŮ NA SERVERU 'příklad @sqldat.com@název_serveru, @str_pred_mess nvarchar(max)='NA SERVERU '[email protected]@název_serveru+' NASTALO CHYBA VYMAZÁNÍ PROCESŮ NEODPOVÍDAJÍCÍCH'; 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 =@,OR_PROESSM AGE @str_P =@COST_PRESSORAGE @str_R_P RECIPIENTS ='RECIPIENT1;RECIPIENT2'; deklarovat @err [email protected]@error; raiserror(@str_mess,16,1);end catch[/expand]
Zde se používá uložená procedura svr.KillFullOldConnect.
Výsledek
Tento článek obsahuje příklad rozšíření funkčnosti běžného databázového mailu a příklad, jak generovat upozornění v tabulkách HTML a poté je e-mailem správcům. Tento přístup umožňuje upozorňovat administrátory na různé problémy v reálném čase nebo po určité době, čímž se minimalizuje výskyt kritického problému a selhání DBMS a serveru, což zase chrání produkci před zpožděním pracovního toku.
Odkazy:
- Sp_send_dbmail
- Databázová pošta
- Srv.KillFullOldConnect