从远程SP

时间:2015-05-11 20:36:08

标签: sql-server stored-procedures sql-server-2005 try-catch sql-server-2000

我找到了一种方法来使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)

1 个答案:

答案 0 :(得分:0)

我认为发生的事情是正确的,因为你正在处理一个例外,所以这项工作并不令人心烦意乱。解决方案可以是日志,因此当异常y捕获时,您插入带有错误描述的行。