आप एक नौकरी बना सकते हैं जो msdb.dbo.sysjobhistory टेबल को हर मिनट (या फिर अक्सर आप चाहते हैं) की जांच करता है। आप एक कतार तालिका लागू करना चाह सकते हैं ताकि आप कभी भी एक बार किसी भी एकल उदाहरण विफलता के लिए संदेश भेजें।
USE msdb;
GO
CREATE TABLE dbo.ReportServerJob_FailQueue
(
job_id UNIQUEIDENTIFIER,
run_date INT,
run_time INT, -- horrible schema, just matching sysjobhistory
sql_message_id INT,
sent BIT NOT NULL DEFAULT 0,
PRIMARY KEY (job_id, run_date, run_time)
);
तो फिर आपका कोड, जिसे आप नौकरी में शेड्यूल कर सकते हैं, बन जाता है:
INSERT dbo.ReportServerJob_FailQueue
(job_id, run_date, run_time, sql_message_id)
SELECT job_id, run_date, run_time, sql_message_id
FROM msdb.dbo.sysjobhistory AS h
WHERE step_id = 0
AND run_status = 0
AND EXISTS
(
SELECT 1 FROM msdb.dbo.sysjobs AS j
INNER JOIN msdb.dbo.syscategories AS c
ON j.category_id = c.category_id
WHERE j.job_id = h.job_id
AND c.name = 'Report Server'
)
AND NOT EXISTS
(
SELECT 1 FROM dbo.ReportServerJob_FailQueue
WHERE job_id = h.job_id
AND run_date = h.run_date
AND run_time = h.run_time
);
अब मुझे लगता है कि आप प्रत्येक विफलता के लिए एक व्यक्तिगत ई-मेल भेजना चाहते हैं, इसलिए यह नौकरी का हिस्सा भी हो सकता है (या एक अलग नौकरी का हिस्सा हो सकता है, हालांकि यह जरूरी नहीं है):
DECLARE
@subject NVARCHAR(4000),
@body NVARCHAR(4000),
@name SYSNAME,
@id UNIQUEIDENTIFIER,
@date INT,
@time INT,
@msg INT;
DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT q.job_id, q.run_date, q.run_time, q.sql_message_id, j.name
FROM dbo.ReportServerJob_FailQueue AS q
INNER JOIN msdb.dbo.sysjobs AS j
ON q.job_id = j.job_id
WHERE q.sent = 0;
OPEN c;
FETCH NEXT FROM c INTO @id, @date, @time, @msg, @name;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @subject = 'Report Server job ' + @name + ' failed.';
SET @body = 'Error number: ' + RTRIM(@msg);
BEGIN TRY
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'default', -- you may need to change this
@recipients = 'foo@bar.com', -- you will need to change this
@subject = @subject,
@body = @body;
UPDATE dbo.ReportServerJob_FailQueue
SET sent = 1
WHERE job_id = @id
AND run_date = @date
AND run_time = @time;
END TRY
BEGIN CATCH
PRINT 'Will have to try that one again later.';
END
FETCH NEXT FROM c INTO @id, @date, @time, @msg, @name;
END
CLOSE c; DEALLOCATE c;
कुछ अन्य विकल्प भी हैं:
- sysjobhistory.message में खींचो
- व्यक्तिगत चरणों को देखें जो विफल रहे
- केवल n मिनट / घंटे में एक बार किसी भी नौकरी के लिए एक संदेश भेजें, भले ही कई विफलताएं हों
- प्रत्येक विफलता के लिए ई-मेल के बजाय, सभी नौकरियों की सूची के साथ एक एकल ई-मेल भेजें
- आप संदेश में run_date और run_time को शामिल करना चाह सकते हैं, क्योंकि ई-मेल भेजा जा सकता है या जल्दी से प्राप्त नहीं हो सकता है जब नौकरी वास्तव में विफल रही हो (मैं इसे यहां शामिल नहीं किया था क्योंकि उनके भयानक डेटा प्रकार विकल्प उस सामान को एक शाही PITA बनाते हुए प्रारूपित करें)
- आप शायद कुछ समय बाद पुरानी पंक्तियों को साफ करना चाहते हैं, इसलिए एक शुद्ध आदेश भी वांछित हो सकता है
यदि डेटाबेस मेल पहले से सेट नहीं है, तो कृपया इस ट्यूटोरियल को देखें ।
आप तीसरे पक्ष के टूल (जैसे SQL सेंट्री इवेंट मैनेजर ) का भी उपयोग कर सकते हैं जो इस सरल को बहुत अधिक बना देगा। पूर्ण प्रकटीकरण: मैं SQL संतरी के लिए काम करता हूं।
AND EXISTS
हिस्से को हटा सकते हैंINSERT/SELECT
। और संभवत: नामReportServerJob_FailQueue
को कुछ अधिक सामान्य में बदल दें। :-)