午後。MS 2K8 BI サーバーでいくつかの SQL エージェント ジョブを実行しています。一部は毎日、他は 1 時間ごと、2 分ごと (別のプロセスのハートビート モニター) です。24 時間体制で数分ごとにデータをインポートするアプリもあります。時折、アップデートとレポートの組み合わせが衝突し、いずれかが通常の 60 秒ではなく、30 分以上ハングすることがあります。
これらの競合状態の根源にたどり着く必要がありますが、それまでの間、たとえば 5 分後に特定のジョブが自動的に終了するように設定したいと考えています。これは SSIS または Windows のスケジュールされたタスクで実行できますが、SQL エージェントで実行する方法がわかりません。これは可能ですか、またはこの種の制御を得るためにタスクを SSIS パッケージにラップする必要がありますか?
参考までに、これが私が最終的に使用したSQLエージェントジョブです。
DECLARE @Cancelled BIT
EXEC dbo.CancelJob @JobName = 'ETL - Daily', @Cancelled = @Cancelled OUT
IF @Cancelled = 1
BEGIN
DECLARE @Success INT
EXEC @Success = msdb..sp_send_dbmail
@profile_name = 'Reporting',
@recipients = 'reporting@mycompany.com',
@subject = 'Cancelled Daily ETL'
IF @Success <> 0 RAISERROR('An error occurred while attempting to send an e-mail.', 16, @Success)
END
...そしてここにコードビハインドがありますCancelJob
:
CREATE PROCEDURE dbo.CancelJob(@JobName VARCHAR(100), @OwnerName VARCHAR(100) = NULL, @Cancelled BIT OUT)
AS BEGIN
IF @OwnerName IS NULL SET @OwnerName = SUSER_NAME()
SET @Cancelled = 0
CREATE TABLE #JobInfo
(
Job_ID UNIQUEIDENTIFIER,
Last_Run_Date INT,
Last_Run_Time INT,
Next_Run_Date INT,
Next_Run_Time INT,
Next_Run_Schedule_ID INT,
Requested_To_Run INT,
Request_Source INT,
Request_Source_ID VARCHAR(100),
Running INT, -- This is the only field we want (sigh)
Current_Step INT,
Current_Retry_Attempt INT,
State INT
)
INSERT INTO #JobInfo
EXEC xp_sqlagent_enum_jobs 1, @OwnerName
DECLARE @Running INT = (SELECT Running FROM #JobInfo AS JI INNER JOIN msdb..sysjobs_view AS J ON JI.Job_ID = J.job_id WHERE J.name = @JobName)
IF @Running = 1
BEGIN
BEGIN TRY
EXEC msdb..sp_stop_job @job_name = @JobName
SET @Cancelled = 1
END TRY
BEGIN CATCH
-- If an error occurs, it is *probably* because the job finished before we could cancel it, which is fine
END CATCH
END
END
GO
xp_sqlagent_enum_jobs
キャッチできないエラーを回避するためのトリックでした。