【发布时间】: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