我找到了一种方法来使SQL预定作业(严重级为16)无法报告失败(因此不会发送电子邮件通知)。我已经修复了我的直接问题,但我想知道为什么有一个失败案例没有报告为失败,以及是否有任何其他令人惊讶的方法错过通知。
我已经设置了两个链接服务器,并尝试在一个查询另一个上面的每小时计划的SQL作业上运行。我今天早上发现 SP中的代码没有运行,但是Job的历史记录是成功的。约伯唯一的步骤是EXEC _testSP
。如果我在SSMS的查询窗口中运行EXEC _testSP
,则会收到以下错误消息:
消息0,级别11,状态0,行0发生严重错误 当前命令。结果(如果有的话)应该被丢弃。
SP的内容包含在TRY ... CATCH
中。如果我删除TRY ... CATCH
,则执行SP会放弃此错误消息:
Msg 213,Level 16,State 7,Line 1 插入错误:列名或提供的值数与表定义不匹配。
这是有道理的。远程表引用了SELECT * FROM
,并且已添加了一些列。我已经删除了asterix并且该作业现在运行正常,但我想确保所有未来异常通过作业失败通知或CATCH
块_testSP
来记录1}}。我不明白为什么这个没有记录,我希望有人可以向我解释。
作业运行并失败并按照我预期的TRY ... CATCH
包装被删除时通知,但我们在TRY ... CATCH
中有一些重要的事情需要保留。
这不是this related question的重复。 Microsoft BOL for TRY...CATCH
表示TRY...CATCH
无法捕获某些例外情况。它可能是相关的,但我发现的是计划作业代理未捕获的异常。
可重现示例:(同时尝试删除TRY...CATCH
包装并查看更改)
USE [RemoteServer].[Database]
CREATE TABLE [Tally](
[ID] [int] IDENTITY(0,1) NOT NULL,
[ID2] [int] NOT NULL
) ON [PRIMARY]
GO
USE [LocalServer]
-- Setup procedure
CREATE PROCEDURE _testSP
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
-- Create destination temp table
CREATE TABLE #tempb (a int)
-- Insert into temp table from remote Tally table
DECLARE @query nvarchar(4000)
SELECT @query = '
SELECT TOP 5 *
FROM [Database].[dbo].Tally
'
INSERT INTO #tempb
EXEC [RemoteServer].[master].[dbo].sp_executesql @query
END TRY BEGIN CATCH
-- Log the exception
-- ...
-- Rethrow the exception
DECLARE @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int;
SELECT
@ErrorMessage = 'Handled Exception: ' + ERROR_MESSAGE() + ' line ' + CAST(ERROR_LINE() as nvarchar(5)),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
END
GO
-- Setup job
DECLARE @database varchar(100)
SELECT @database = DB_Name()
EXEC msdb.dbo.sp_add_job
@job_name = '_testSPJob'
EXEC msdb.dbo.sp_add_jobstep
@job_name = '_testSPJob',
@step_name = '_testSPJob',
@subsystem = N'TSQL',
@command = 'EXEC _testSP',
@database_name = @database
EXEC msdb.dbo.sp_add_jobserver
@job_name = '_testSPJob',
@server_name = @@SERVERNAME
GO
-- Manual execution fails
EXEC _testSP
GO
-- Run job
EXEC msdb.dbo.sp_start_job
@job_name = '_testSPJob'
WAITFOR DELAY '00:00:02'
GO
-- Select job history
SELECT * FROM msdb.dbo.sysjobhistory
WHERE step_name = '_testSPJob'
ORDER BY run_date, run_time
GO
我真的需要说服老板们下车SQL 2000.这是我的软件版本。也许这在SQL的更高版本中得到修复?
SSMS Version: 2012 (11.0.5058.0)
Local DB: SQL 2005 (9.0.5069)
Remote DB: SQL 2000 (8.0.760)
答案 0 :(得分:0)
我认为发生的事情是正确的,因为你正在处理一个例外,所以这项工作并不令人心烦意乱。解决方案可以是日志,因此当异常y捕获时,您插入带有错误描述的行。