Въведение
Често има нужда по някакъв начин да информирате администраторите за проблемите със сървъра. Известията обикновено са разделени на 2 типа:
1) известия в реално време, т.е. тези, които трябва да идват незабавно, когато възникне проблем
2) забавени известия, т.е. тези, които идват след доста дълго време (повече от 1 час) след възникване на проблем.
В моята работа беше необходимо да разширя функционалността на обикновената SQL Server Database Mail.
В тази статия ще разгледаме пример как да генерирате известия в HTML таблици и след това да ги изпращате до администраторите.
Решение
1. Конфигуриране на Database Mail
2. Създайте таблица за получатели:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Recipient]( [Recipient_GUID] [уникален идентификатор] ROWGUIDCOL NOT NULL, [Recipient_Name] [25 recipient_Name] [nvard. Recipient_Code] [nvarchar](10) NOT NULL, // кодът на получателя [IsDeleted] [bit] NOT NULL, // индикатор за изтриване (независимо дали се използва получател или не) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Recipient ] ПЪРВЕН КЛУСТРИРАН ( [Recipient_GUID] ASC) С (PAD_INDEX =ИЗКЛЮЧЕНО, STATISTICS_NORECOMPUTE =ИЗКЛЮЧЕНО, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ, ALLOW_PAGE_LOCKS =ON) ON [NSTRALURY_PAGE_LOCKS =ON) (PAD_INDEX =ИЗКЛЮЧЕНО, STATISTICS_NORECOMPUTE =ИЗКЛЮЧЕНО, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ, ALLOW_PAGE_LOCKS =ВКЛ) ON [PRIMARY], CONSTRAINT [AK_Recipient_Name] UNIQUE NOCIPIENT_Name] (UNIQUE NOCILUSTEENT_NAME) F, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ, ALLOW_PAGE_LOCKS =ВКЛ.) ВКЛЮЧЕНО [ОСНОВНА]) НА [ОСНОВНА]ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[Получател] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_Recipient_Recipient_GUID] GO [DF_Recipient_Recipient_GUID] srv].[Получател] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_Recipient_IsDeleted] ПО ПОДРАЗБИРАНЕ ((0)) ЗА [IsDeleted]ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[Получател] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_Recipient_InsertUTCDate] ПО ПОДРАЗБИРАНЕ (getutcdate()) FORTE][/expand]
3. Създайте таблица за адресите на получателите:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[Address]( [Address_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL, [Recipient_GUID] [Uniqueidentifier, recipient] [uniqueidentifier, char] 255) NOT NULL, // имейл [IsDeleted] [bit] NOT NULL, // индикатор за изтриване (независимо дали имейлът се използва или не) [InsertUTCDate] [datetime] NOT NULL, CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED ( [Address_GUID] ASC )С (PAD_INDEX =ИЗКЛ., STATISTICS_NORECOMPUTE =ИЗКЛ., IGNORE_DUP_KEY =ИЗКЛ., ALLOW_ROW_LOCKS =ВКЛ., ALLOW_PAGE_LOCKS =ВКЛ.) ВКЛ. , STATISTICS_NORECOMPUTE =ИЗКЛЮЧЕНО, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛЮЧЕНО, ALLOW_PAGE_LOCKS =ON) ON [PRIMARY]) ON [PRIMARY]GOALTER TABLE [srv].[Address] ADD CONSTRAINT [DF_GUALID]Address_Address(Queen_Address) ТАБЛИЦА НА ГОЛТАРИТЕ [ srv].[Адрес] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_Address_IsDeleted] ПО ПОДРАЗБИРАНЕ ((0)) ЗА [IsDeleted]ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[Адрес] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_Address_InsertUTCDate] ПО ПОДРАЗБИРАНЕ (getutcdate()) ЗА [GODate][/expand]
4. Създайте таблица за опашка от съобщения:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfo]( [ErrorInfo_GUID] [uniqueidentifier] NOT NULL, [ERROR_TITLE] [nvarchar](max title) [nvarchar](max title) [nvarchar_ERROR] (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] [dat etime] NOT NULL, [IsRealTime] [bit] NOT NULL, // индикатор в реално време [InsertUTCDate] [datetime] NULL, CONSTRAINT [PK_ErrorInfo] ПЪРВИЧЕН КЛУСТЕР ( [ErrorInfo_GUID] ASC)WITH (PAD_INDEX =OFF, STATICOMPUSTICS_OFF, STATICOMPUSTICS OFF, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ, ALLOW_PAGE_LOCKS =ВКЛ.) ВКЛЮЧЕНО [ОСНОВНО]) НА [ОСНОВНО] TEXTIMAGE_ON [PRIMARY] ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[ErrorInfo] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_Error] ТАБЛИЦА [srv].[ErrorInfo] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfo_InsertDate] ПО ПОДРАЗБИРАНЕ (getdate()) ЗА [InsertDate] ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[ErrorInfo] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfo_StartDate] TFAULT [Date) GOALTER (Дата по подразбиране)] srv].[ErrorInfo] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfo_FinishDate] ПО ПОДРАЗБИРАНЕ (getdate()) ЗА [FinishDate] ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[ErrorInfo] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfo_Count] ПО ПОДРАЗБИРАНЕ ((1)) ЗА TABLE [Count] .[ErrorInfo] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF__ErrorInfo__Updat__5FFEE747] DEFAU LT (getdate()) ЗА [UpdateDate]GOALTER TABLE [srv].[ErrorInfo] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfo_IsRealTime] ПО ПОДРАЗБИРАНЕ ((0)) ЗА [IsRealTime]GOALTER TABLE [srv].[ErrorInfo] ДОБАВЯНЕ НА CONSTRAOR (Dad_Info_Info) DEDF_Info_IsRealTime. getutcdate()) ЗА [InsertUTCDate]GO[/expand]
5. Създайте архивна таблица за съобщения, изпратени от опашката за съобщения:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [srv].[ErrorInfoArchive]( [ErrorInfo_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL, [ERROR_TITLE](ncharNULL,maxvar) ) 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, [получатели] [nvarchar](max) NULL, [InsertDate] [datetime] NOT NULL, [StartDate] [datetime] NOT NULL, [FinishDate] [datetime] НЕ NULL, [Count] [ int] NOT NULL, [UpdateDate] [datetime] NOT NULL, [IsRealTime] [bit] NOT NULL, [InsertUTCDate] [datetime] NULL, CONSTRAINT [PK_ArchiveErrorInfo] ПЪРВИЧЕН КЛЮЧ КОЛУСТРИРАН ([Error ADSCInfo_INDEX]PA =STATISTICS_NORECOMPUTE =ИЗКЛЮЧЕНО, IGNORE_DUP_KEY =ИЗКЛЮЧЕНО, ALLOW_ROW_LOCKS =ВКЛ., ALLOW_PAGE_LOCKS =ВКЛ.) ВКЛ. [ОСНОВНО]) НА [ОСНОВНО] TEXTIMAGE_ON [ОСНОВНА]ГОЛТА R ТАБЛИЦА [srv].[ErrorInfoArchive] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfoArchive_ErrorInfo_GUID] ПО ПОДРАЗБИРАНЕ (newsequentialid()) ЗА [ErrorInfo_GUID]GOALTER TABLE [srv].[ErrorInfoArchive] [ErrorInfoArchive] [ErrorInfoArchive] ДОБАВЯНЕ НА CONSTRACT (DarrorInfoArchive) [DarrorInfoArchive]. [srv].[ErrorInfoArchive] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfoArchive_StartDate] ПО ПОДРАЗБИРАНЕ (getdate()) ЗА [StartDate] ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[ErrorInfoArchive] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfoArchive_StartDate] ПО ПРАВО (getdate()) ЗА [StartDate] ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[ErrorInfoArchive] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfoArchive_StartDate] TAPNISH (GOALTER) ].[ErrorInfoArchive] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfoArchive_Count] ПО ПОДРАЗБИРАНЕ ((1)) ЗА [Брой] ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[ErrorInfoArchive] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfoArchive_UpdateDate] [DFAULT] (GETDATE) ПО ПОДРАЗБИРАНЕ (getdate)]. [ErrorInfoArchive] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfoArchive_IsRealTime] ПО ПОДРАЗБИРАНЕ ((0)) ЗА [IsRealTime] ТАБЛИЦА НА ГОЛТЪРИТЕ [srv].[ErrorInfoArchive] ДОБАВЯНЕ НА ОГРАНИЧЕНИЕ [DF_ErrorInfoArchive_Insert(GOOGETUTC) DEFAULT (GOOLTER) повторно>[/expand]
Тази информация е необходима за историята. Освен това тази таблица трябва да бъде изчистена от много стари данни (например по-стари от месец).
6. Създайте съхранена процедура, която регистрира ново съобщение в опашката за съобщения:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[ErrorInfoIncUpd] @ERROR_TITLE nvarchar(max), @ERROR_PRED_MESSAGE nvarchar(max), @char(char_ESS(maxLINE), nvarchar(max), @ERROR_ERROR(maxLINE), nvarchar(max), @ERROR_ESS(max). nvarchar(max), @ERROR_PROCEDURE nvarchar(max), @ERROR_POST_MESSAGE nvarchar(max), @RECIPIENTS nvarchar(max), @StartDate datetime=null, @FinishDate datetime=null, @IsRealTime bit =0ASBEGIN /* Грешката при регистриране таблицата да бъде изпратена по имейл, ако таблицата вече има запис със същото заглавие, съдържание и подател, крайната дата на грешката, датата на актуализиране на записа, както и броят на грешките ще се промени */ SET NOCOUNT НА; декларира @ErrorInfo_GUID уникален идентификатор; изберете началото 1 @ErrorInfo_GUID=ErrorInfo_GUID от srv.ErrorInfo където ([email protected]_TITLE или @ERROR_TITLE е нула) и [email protected] и ([email protected]_MESSAGE или @ERROR_MESSAGE е null@sqldatMESSAGE). или @ERROR_PRED_MESSAGE е нула) и ([email protected]_POST_MESSAGE или @ERROR_POST_MESSAGE е нула) и ([email protected] или @IsRealTime е нула); if(@ErrorInfo_GUID е null) започнете вмъкване в srv.ErrorInfo ( ERROR_TITLE ,ERROR_PRED_MESSAGE ,ERROR_NUMBER ,ERROR_MESSAGE ,ERROR_LINE ,ERROR_PROCEDURE ,ERROR_POST_MESSAGE ,RECIPIENTS ,IsRealTime ,FinishMESSTENUMBERPRED)select@FishMESSTE_ERROR ERROR_LINE ,@ERROR_PROCEDURE ,@ERROR_POST_MESSAGE ,@RECIPIENTS ,@IsRealTime ,isnull(@StartDate, getdate()) ,isnull(@FinishDate,getdate()) end else започва актуализация srv.ErrorInfo set FinishDate=getdate(), [Count]=[Count]+1, UpdateDate=getdate() където [email protected]_GUID; крайENDGO[/expand]
7. Създайте съхранена процедура, която връща низ от адресите по кода или основния имейл адрес на получател:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetRecipients]@Recipient_Name nvarchar(255)=NULL,@Recipient_Code nvarchar(10)/Recipient_Code nvarchar(10)/Recipients Процедурата за outchar(10)=NULL създаване на известия по имейл*/ASBEGIN SET NOCOUNT ON; задайте @Recipients=''; изберете @[email protected]+d.[Адрес]+';' от srv.Recipient като r вътрешно присъединяване srv.[Адрес] като d на r.Recipient_GUID=d.Recipient_GUID, където ([email protected]_Name или @Recipient_Name е NULL) и ([email protected]_Code или @Recipient_Code) и @Recipient_Code) и r.IsDeleted=0 и d.IsDeleted=0; --подреждане по r.InsertUTCDate desc, d.InsertUTCDate desc; if(len(@Recipients)>0) задайте @Recipients=substring(@Recipients,1,len(@Recipients)-1);ENDGO[/expand]
8. Създайте необходимите функции за работа с дати и час:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [rep].[GetDateFormat] ( @dt datetime, // входна дата @format int=0 // предварително зададен формат)ВЪРНА nvarchar(255) da AS/* низ според посочения формат и въведената дата Вмъква нули, където е необходимо:формат на въведена дата резултат 0 17.4.2014 "17.04.2014" 1 17.4.2014 "04.2014" 1 8.11.2014 "11.2014" 2014 "2014". */BEGIN DECLARE @res nvarchar(255); ДЕКЛАРИРАНЕ @day int=ДЕН(@dt); ДЕКЛАРИРАНЕ @month int=MONTH(@dt); ДЕКЛАРИРАНЕ @година int=ГОДИНА(@dt); if(@format=0) begin set @res=IIF(@day<10,'0'+cast(@day като nvarchar(1)), cast(@day като nvarchar(2)))+'.'; set @[email protected]+IIF(@month<10,'0'+cast(@month като nvarchar(1)), cast(@month като nvarchar(2)))+'.'; задайте @[email protected]+cast(@year като nvarchar(255)); край else if(@format=1) начало set @res=IIF(@month<10,'0'+cast(@month като nvarchar(1)), cast(@month като nvarchar(2)))+'. '; задайте @[email protected]+cast(@year като nvarchar(255)); край else if(@format=2) начало set @res=cast(@year като nvarchar(255)); end RETURN @res;ENDGOUSE [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [rep].[GetTimeFormat] ( @dt datetime, // входно време @format int=0 // предварително зададен формат)RETURNS nvarchar/*Returns) време като низ според посочения формат и времето за въвеждане Вмъква нули, където е необходимо:формат на входно време резултат 0 17:04 "17:04:00" 1 17:04 "17:04" 1 8:04 "08:04 " 2 17:04 "17"*/ЗАПОЧНЕТЕ ДЕКЛАРИРАНЕ @res nvarchar(255); ДЕКЛАРИРАНЕ @hour int=DATEPART(HOUR, @dt); ДЕКЛАРИРАНЕ @min int=DATEPART(MINUTE, @dt); ДЕКЛАРИРАНЕ @sec int=DATEPART(SECOND, @dt); if(@format=0) започнете set @res=IIF(@hour<10,'0'+cast(@hour като nvarchar(1)), cast(@hour като nvarchar(2)))+':'; set @[email protected]+IIF(@min<10,'0'+cast(@min като nvarchar(1)), cast(@min като nvarchar(2)))+':'; задайте @[email protected]+IIF(@sec<10,'0'+cast(@sec като nvarchar(1)), cast(@sec като nvarchar(2))); край else if(@format=1) начало set @res=IIF(@hour<10,'0'+cast(@hour като nvarchar(1)), cast(@hour като nvarchar(2)))+':'; задайте @[email protected]+IIF(@min<10,'0'+cast(@min като nvarchar(1)), cast(@min като nvarchar(2))); край else if(@format=2) начало set @res=IIF(@hour<10,'0'+cast(@hour като nvarchar(1)), cast(@hour като nvarchar(2))); край RETURN @res;ENDGO[/expand]
9. Създайте съхранена процедура, която създава HTML отчет за съобщения под формата на таблица:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABASE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[GetHTMLTable] @recipients nvarchar(max) ,@dt datetime // до коя дата да прочететеASBEGIN /* генерира HTML-код за НЯМА таблица */ON SET COUNT; декларира @body nvarchar(max); декларира @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] nvar) (max) ,[ERROR_PROCEDURE] nvarchar(max) ,[ERROR_POST_MESSAGE] nvarchar(max) ,[InsertDate] datetime ,[StartDate] datetime ,[FinishDate] datetime ,[Count] int ); деклариране на @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(maxPRED_MESSAGE)xnvarvar (макс.) ,@InsertDate datetime ,@StartDate datetime ,@FinishDate datetime ,@Count int int int in @tbl( [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDAGE] ] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] ) изберете първите 100 [ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ERROR_POST_MESSAGE] ,[InsertDate] ,[StartDate] ,[FinishDate] ,[Count] от [srv].[ErrorInfo] където ([RECIPIENTS]example.com@sqld. ) или (@recipients Е NULL) и InsertDate'; set @example@sqldat.com+' '; set @[email protected]+' '; while((изберете топ 1 1 от @tbl)>0) започнете набор @[email protected]+''; set @[email protected]+'№ п/п'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'ДАТА'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'ГРЕШКА'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'ОПИСАНИЕ'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'КОД НА ГРЕШКА'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'СЪОБЩЕНИЕ'; 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]+'НОМЕР НА ЛИНИЯ'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'PROCEDURE'; set @[email protected]+' '; set @[email protected]+''; set @[email protected]+'ЗАБЕЛЕЖКА'; set @[email protected]+' '; set @[email protected]+''; изберете началото 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] от @tbl подреждане по InsertDate asc; set @[email protected]+' '; краен набор @[email protected]+''; изберете @body;ENDGO'; задайте @[email protected]+cast(@ID като nvarchar(max)); set @[email protected]+' '; set @[email protected]+''; set @[email protected]+rep.GetDateFormat(@InsertDate, по подразбиране)+' '+rep.GetTimeFormat(@InsertDate, по подразбиране); // cast(@InsertDate като 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 като nvarchar(max)); set @[email protected]+' '; set @[email protected]+''; set @[email protected]+rep.GetDateFormat(@FinishDate, по подразбиране)+' '+rep.GetTimeFormat(@FinishDate, по подразбиране); //cast(@FinishDate като 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]+' '; изтрийте от @tbl, където [email protected]; set @[email protected]+'[/expand]
10. Създайте съхранена процедура, която изпраща съобщения:
[expand title =”Код”]
ИЗПОЛЗВАЙТЕ [DATABAE_NAME]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE PROCEDURE [srv].[RunErrorInfoProc] @IsRealTime bit =0 // режим на изпращане (1-реално време)ASBEGIN /* изпращане на известия за грешки с посочения режим */ ON SET NO COUNT; декларираме @dt datetime=getdate(); декларира @tbl таблица(Получатели nvarchar(max)); декларира @recipients nvarchar(max); декларира @recipient nvarchar(255); декларира @result nvarchar(max)=''; декларира @recp nvarchar(max); декларира @ind int; декларираме @recipients_key nvarchar(max); // получаване на всички необходими съобщения вмъкнете в @tbl(Recipients) изберете [РЕЦИПИЕНТИ] от srv.ErrorInfo където InsertDate0) започнете //получаване на получатели изберете отгоре (1) @recipients=Получатели от @tbl; задайте @[email protected]; задайте @result=''; // за всеки получател while(len(@recipients)>0) започва набор @ind=CHARINDEX(';', @recipients); if(@ind>0) започва набор @recipient=substring(@recipients,1, @ind-1); set @recipients=substring(@recipients,@ind+1,len(@recipients)[email protected]); край друго начало set @[email protected]; задайте @recipients=''; край; // получаваме имейли на получатели exec [srv].[GetRecipients] @[email protected], @[email protected] out; if(len(@recp)=0) започнете exec [srv].[GetRecipients] @[email protected], @[email protected] изход; if(len(@recp)=0) задайте @[email protected]; край // разделени със символ ';' set @[email protected]@sqldat.com+';'; краен набор @result=substring(@result,1,len(@result)-1); задайте @[email protected]; // получаваме HTML-отчет с посочените получатели и вмъкване на дата в @rec_body(Body) exec srv.GetHTMLTable @[email protected]_key, @[email protected]; // получаване на HTML-отчет изберете отгоре (1) @body=Тяло от @rec_body; // действителното изпращане на EXEC msdb.dbo.sp_send_dbmail // изпращане на имейл администраторски профил, който създадохме @profile_name ='ALARM', // имейл на получател @recipients =@recipients, // текст на съобщение @body =@body, // Тема @subject =N'ИНФОРМАЦИЯ ЗА ГРЕШКИ ПРИ ИЗПЪЛНЕНИЕ', @body_format='HTML'--, // Например, нека добавим резултатите от произволна SQL заявка към съобщението [email protected] =@query--'SELECT TOP 10 име FROM sys.objects'; изтрийте от @tbl, където [email protected]_key; изтрийте от @rec_body; end // архивиране на изпратените съобщения INSERT INTO [srv].[ErrorInfoArchive] ([ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINE] ,[ERROR_PROCEDURE] ,[ESSAGE]ERRORPOST ,[ESSAGE]ERRORPOST ,[ESSAGE] ПОЛУЧАТЕЛИ] ,[Начална дата] ,[Крайна дата] ,[Брой] ,IsRealTime ) ИЗБЕРЕТЕ [ErrorInfo_GUID] ,[ERROR_TITLE] ,[ERROR_PRED_MESSAGE] ,[ERROR_NUMBER] ,[ERROR_MESSAGE] ,[ERROR_LINECED] ,[ERROR_LINECED] ,[OST]ERROR_PROGESS [ПОЛУЧАТЕЛИ] ,[Начална дата] ,[Крайна дата] ,[Брой] ,IsRealTime FROM [srv].[ErrorInfo] където [email protected] и InsertDate [/expand]
Тази съхранена процедура взема всяко съобщение от опашката със съобщения и го обвива в HTML отчет под формата на таблица. За получателите, въз основа на техния код или основен имейл адрес, той създава низ, състоящ се от имейл адреси, до които се изпраща съобщение. По този начин се обработват всички избрани съобщения. Тук се използва съхранената процедура msdb.dbo.sp_send_dbmail.
11. Създайте две задачи в Агент (първата е за известия в реално време (график 1 път в минута), втората е за прости известия (график 1 път на час)). Добавете следното към кода на задачата:
ИЗПЪЛНЕТЕ [ИМЕ_БАЗА_ДАНИ].[srv].[RunErrorInfoProc] @IsRealTime=0; // 0 - за прости съобщения и 1 - за съобщения в реално времеЕто пример за отчитане на грешки:
[expand title=”Код”]
започнете опитайте exec [DATABASE_NAME].[srv].[KillFullOldConnect];end trybegin catch declare @str_mess nvarchar(max)=ERROR_MESSAGE(), @str_num nvarchar(max)=cast(ERROR_NUMBER() като nvarchar(max) ), @str_line nvarchar(max)=cast(ERROR_LINE() като nvarchar(max)), @str_proc nvarchar(max)=ERROR_PROCEDURE(), @str_title nvarchar(max)='ИЗТРИВАНЕ НА НЕОТГОВЯЩИ ПРОЦЕСИ НА СЪРВЪРА 'пример @sqldat.com@servername, @str_pred_mess nvarchar(max)='ГРЕШКАТА ИЗТРИВАНЕ НА ПРОЦЕСИ НЕ ОТГОВОР НА СЪРВЪРА '[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 =@ERROR_PROCEDURE =@str_PROCEDURE =@str_NESS ПОЛУЧАТЕЛИ ='ПОЛУЧАТЕЛ1; ПОЛУЧАТЕЛ2'; декларира @err [email protected]@error; raiserror(@str_mess,16,1);край улов[/expand]
Тук се използва съхранената процедура svr.KillFullOldConnect.
Резултат
Тази статия включва пример за разширяване на функционалността на обикновена поща от база данни и пример за това как да генерирате известия в HTML таблици и след това да ги изпращате по имейл до администраторите. Този подход позволява уведомяване на администраторите за различни проблеми в реално време или след определено време, като по този начин се свежда до минимум появата на критичен проблем и повреда на СУБД и сървъра, което от своя страна предпазва производството от забавяне на работния процес.
Препратки:
- Sp_send_dbmail
- Поща от база данни
- Srv.KillFullOldConnect