T-SQL : 远程存储过程结果有时为空

T-SQL : remote stored procedure result is sometimes empty

我在调用远程存储过程时有一个奇怪的行为:通常它按预期工作,但有时我得不到存储过程的结果。

详细说明:我有两个存储过程。第一个是调用第二个,由第三个触发,第三个由 SQL Server Agent 触发,但我会关注 #1 和 #2。

这里是存储过程 #1(稍微简化了一点):

CREATE PROCEDURE [dbo].[spCalculateForecast]
AS
BEGIN
    DECLARE @ForecastResult TABLE(
        [ProductId] INT NOT NULL,
        [Forecast30] DECIMAL(13,3) NOT NULL,
        [Forecast60] DECIMAL(13,3) NOT NULL,
        [Forecast90] DECIMAL(13,3) NOT NULL,
        [Forecast120] DECIMAL(13,3) NOT NULL
    )

    INSERT INTO @ForecastResult
        EXECUTE sp_execute_external_script
                @language = N'R',
                @script = N'

    DO SOME MAGIC

    OutputDataSet <- forecast.result
    ',
    @input_data_1 = N'
        SELECT *
        FROM Forecast_Data
        ORDER BY ProductId, Date',
    @input_data_1_name = N'forecast.data';

    IF NOT EXISTS (SELECT TOP 1 1 FROM @ForecastResult)
    BEGIN
        RAISERROR ('No forecast results generated.', 18, 1);
        RETURN
    END

    SELECT * FROM @ForecastResult
END

如您所见,我添加了一个检查来验证存储过程 #1 的结果是否为空。

在存储过程 #2 中调用 #1:

CREATE PROCEDURE [dbo].[spExecuteForecast]
AS
BEGIN
    BEGIN TRY
        DECLARE @ForecastResult TABLE(
            [ProductId] INT NOT NULL,
            [Forecast30] DECIMAL(13,3) NOT NULL,
            [Forecast60] DECIMAL(13,3) NOT NULL,
            [Forecast90] DECIMAL(13,3) NOT NULL,
            [Forecast120] DECIMAL(13,3) NOT NULL
        )

        INSERT INTO @ForecastResult
            EXEC [RemoteServer].[RemoteDB].[dbo].[spCalculateForecast]

        IF NOT EXISTS (SELECT TOP 1 1 FROM @ForecastResult)
        BEGIN
            RAISERROR ('Forecast result empty', 18, 1)
        END

        -- DO SOMETHING WITH THE RESULT
    BEGIN CATCH
        -- log error
    END CATCH
END

在存储过程 #2 中,我还添加了一个检查来验证存储过程 #1 的结果是否为空。

如前所述,两个存储过程都按预期工作,除非发生错误。然后是存储过程 #2 的每次错误 'Forecast result empty'。

对我来说,存储过程 #1 似乎创建了一个有效结果,但它无法被存储过程 #2 提取。我认为这可能是一个连接问题,但我希望有一条错误消息表明这一点,或者如果它在创建预测结果时出现问题,我希望一条错误消息表明这一点或至少是存储过程 #1 的验证错误。

有人知道这里发生了什么吗?

提前致谢。

经过长时间的搜索并尝试了所有我能想到的方法后,我 运行 使用 SQL Server Profiler 进行了监控(正如@Amirhossein 所建议的,谢谢)。监控显示错误,这将我指向了错误的方向。但监控还包含了 RPC 调用的开始和结束时间,正好是 20 分钟。对我来说唯一可能的答案是:超时。 我有一个新的搜索方向并找到了这个答案:

一个简短的 SQL 语句告诉我,RPC 超时设置为 20 分钟。

SELECT * FROM sys.configurations WHERE name = 'remote query timeout (s)'

所以,简而言之:我没有得到数据也没有错误,因为 TRY CATCH 没有捕获超时

我增加了超时时间,现在一切正常。