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 没有捕获超时
我增加了超时时间,现在一切正常。
我在调用远程存储过程时有一个奇怪的行为:通常它按预期工作,但有时我得不到存储过程的结果。
详细说明:我有两个存储过程。第一个是调用第二个,由第三个触发,第三个由 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 没有捕获超时
我增加了超时时间,现在一切正常。