Въведение
Често има нужда по някакъв начин да информирате администраторите за проблемите със сървъра. Известията обикновено са разделени на 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 където (example@sqldat.com_TITLE или @ERROR_TITLE е нула) и example@sqldat.com и (example@sqldat.com_MESSAGE или @ERROR_MESSAGE е null@sqldatMESSAGE). или @ERROR_PRED_MESSAGE е нула) и (example@sqldat.com_POST_MESSAGE или @ERROR_POST_MESSAGE е нула) и (example@sqldat.com или @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() където example@sqldat.com_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=''; изберете @example@sqldat.com+d.[Адрес]+';' от srv.Recipient като r вътрешно присъединяване srv.[Адрес] като d на r.Recipient_GUID=d.Recipient_GUID, където (example@sqldat.com_Name или @Recipient_Name е NULL) и (example@sqldat.com_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 @example@sqldat.com+IIF(@month<10,'0'+cast(@month като nvarchar(1)), cast(@month като nvarchar(2)))+'.'; задайте @example@sqldat.com+cast(@year като nvarchar(255)); край else if(@format=1) начало set @res=IIF(@month<10,'0'+cast(@month като nvarchar(1)), cast(@month като nvarchar(2)))+'. '; задайте @example@sqldat.com+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 @example@sqldat.com+IIF(@min<10,'0'+cast(@min като nvarchar(1)), cast(@min като nvarchar(2)))+':'; задайте @example@sqldat.com+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)))+':'; задайте @example@sqldat.com+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 @example@sqldat.com+' '; while((изберете топ 1 1 от @tbl)>0) започнете набор @example@sqldat.com+''; set @example@sqldat.com+'№ п/п'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'ДАТА'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'ГРЕШКА'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'ОПИСАНИЕ'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'КОД НА ГРЕШКА'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'СЪОБЩЕНИЕ'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'START'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'FINISH'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'NUMBER'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'НОМЕР НА ЛИНИЯ'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'PROCEDURE'; set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+'ЗАБЕЛЕЖКА'; set @example@sqldat.com+' '; set @example@sqldat.com+''; изберете началото 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 @example@sqldat.com+' '; краен набор @example@sqldat.com+''; изберете @body;ENDGO'; задайте @example@sqldat.com+cast(@ID като nvarchar(max)); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+rep.GetDateFormat(@InsertDate, по подразбиране)+' '+rep.GetTimeFormat(@InsertDate, по подразбиране); // cast(@InsertDate като nvarchar(max)); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_TITLE,''); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_PRED_MESSAGE,''); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_NUMBER,''); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_MESSAGE,''); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+rep.GetDateFormat(@StartDate, default)+' '+rep.GetTimeFormat(@StartDate, default); //cast(@StartDate като nvarchar(max)); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+rep.GetDateFormat(@FinishDate, по подразбиране)+' '+rep.GetTimeFormat(@FinishDate, по подразбиране); //cast(@FinishDate като nvarchar(max)); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+cast(@Count as nvarchar(max)); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_LINE,''); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_PROCEDURE,''); set @example@sqldat.com+' '; set @example@sqldat.com+''; set @example@sqldat.com+isnull(@ERROR_POST_MESSAGE,''); set @example@sqldat.com+' '; изтрийте от @tbl, където example@sqldat.com; set @example@sqldat.com+'[/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; задайте @example@sqldat.com; задайте @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)example@sqldat.com); край друго начало set @example@sqldat.com; задайте @recipients=''; край; // получаваме имейли на получатели exec [srv].[GetRecipients] @example@sqldat.com, @example@sqldat.com out; if(len(@recp)=0) започнете exec [srv].[GetRecipients] @example@sqldat.com, @example@sqldat.com изход; if(len(@recp)=0) задайте @example@sqldat.com; край // разделени със символ ';' set @example@sqldat.comexample@sqldat.com+';'; краен набор @result=substring(@result,1,len(@result)-1); задайте @example@sqldat.com; // получаваме HTML-отчет с посочените получатели и вмъкване на дата в @rec_body(Body) exec srv.GetHTMLTable @example@sqldat.com_key, @example@sqldat.com; // получаване на HTML-отчет изберете отгоре (1) @body=Тяло от @rec_body; // действителното изпращане на EXEC msdb.dbo.sp_send_dbmail // изпращане на имейл администраторски профил, който създадохме @profile_name ='ALARM', // имейл на получател @recipients =@recipients, // текст на съобщение @body =@body, // Тема @subject =N'ИНФОРМАЦИЯ ЗА ГРЕШКИ ПРИ ИЗПЪЛНЕНИЕ', @body_format='HTML'--, // Например, нека добавим резултатите от произволна SQL заявка към съобщението example@sqldat.com =@query--'SELECT TOP 10 име FROM sys.objects'; изтрийте от @tbl, където example@sqldat.com_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] където example@sqldat.com и 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)='ГРЕШКАТА ИЗТРИВАНЕ НА ПРОЦЕСИ НЕ ОТГОВОР НА СЪРВЪРА '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 =@ERROR_PROCEDURE =@str_PROCEDURE =@str_NESS ПОЛУЧАТЕЛИ ='ПОЛУЧАТЕЛ1; ПОЛУЧАТЕЛ2'; декларира @err example@sqldat.com@error; raiserror(@str_mess,16,1);край улов[/expand]
Тук се използва съхранената процедура svr.KillFullOldConnect.
Резултат
Тази статия включва пример за разширяване на функционалността на обикновена поща от база данни и пример за това как да генерирате известия в HTML таблици и след това да ги изпращате по имейл до администраторите. Този подход позволява уведомяване на администраторите за различни проблеми в реално време или след определено време, като по този начин се свежда до минимум появата на критичен проблем и повреда на СУБД и сървъра, което от своя страна предпазва производството от забавяне на работния процес.
Препратки:
- Sp_send_dbmail
- Поща от база данни
- Srv.KillFullOldConnect