【问题标题】:T-SQL : remote stored procedure result is sometimes emptyT-SQL:远程存储过程结果有时为空
【发布时间】:2020-03-03 06:51:43
【问题描述】:

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

详细说明:我有两个存储过程。第一个调用第二个,由第三个触发,由 SQL Server 代理触发,但我将重点关注 #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 中的每次错误“预测结果为空”。

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

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

提前致谢。

【问题讨论】:

  • 嗨...毫无疑问,一个关于 If exists 的事实,你不需要使用 top 1 因为 IF Exists 语句 stop 会找到第一行的已提交条件。
  • 使用分析器查找问题,如果你有空结果,SP1中的问题,你可以在SP2中设置参数验证。并引发错误此冲突以查找问题。
  • 它是空的,因为你没有在最底层的过程中进行错误处理吗?
  • @Amirhossein:感谢您对 IF EXSITS 的提示。关于“使用分析器”:我不能。如果我手动运行 SP,我从来没有遇到过这个问题。每天晚上都会调用 SP,并且此问题最多发生。每月 2 次。所以它不能手工复制。
  • @SMor:也谢谢你。你的意思是我必须在 SP #1 添加一个 TRY CATCH 吗?通常,错误会从 SP #1 冒泡到 #2。我在 SP #1 中使用 RAISERROR 对其进行了测试,我可以在 #2 中捕获它(手动运行)。

标签: sql-server tsql rpc sql-server-2017


【解决方案1】:

在搜索了很长时间并尝试了我能想到的一切之后,我使用 SQL Server Profiler 运行了一个监控(正如@Amirhossein 建议的那样,谢谢你)。监控显示错误,将我指向错误的方向。但监控还包含 RPC 调用的开始和结束时间,正好是 20 分钟。对我来说唯一可能的答案是:超时。 我有一个新的搜索方向,找到了这个答案:https://stackoverflow.com/a/54531530/12997628

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

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

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

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

【讨论】:

    猜你喜欢
    • 2018-10-03
    • 2013-05-28
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2015-06-03
    • 2010-11-20
    相关资源
    最近更新 更多