尽管结果不为零,但存储过程除以零

时间:2019-05-09 16:55:14

标签: sql sql-server

我有一个存储过程正在调用两个其他存储过程,它们返回正确的值并且非零。

我已经尽一切努力在这个问题上找到了

ALTER PROCEDURE [dbo].[updateBudgetCalc](@JobNum AS nvarchar(50))
AS
BEGIN
    DECLARE @estHrs float
    DECLARE @totHrs float


    EXEC @totHrs = PanelShop.dbo.getHoursTotal @JobNum 


    EXEC @estHrs = PanelShop.dbo.getHoursEst @JobNum  


    UPDATE ActiveList SET PercentOfBudget = @estHrs/@totHrs WHERE Jobnum = @JobNum
    return (@totHrs)
END;

执行此SP时,我得到:

  

消息8134,级别16,状态1,过程updateBudgetCalc,第14行   除以零错误。

它确实将@totHrs评估为null 然而,在结果中,我看到它查询了两个表并返回了totHrs的非零值2.22000 的estHrs值为5.25

2 个答案:

答案 0 :(得分:6)

变量@estHrs@totHrs保存执行嵌套存储过程的结果。如果执行时没有错误,则这些结果将为0,这就是您Divide by zero错误的原因。

重要的是要使存储过程的执行结果与该过程返回的结果集有所不同。

如果要从存储过程返回单个值,请使用output parameter。如果您的过程返回了结果集,则可以将该结果插入表中并从该表中选择适当的值。

具有输出参数的存储过程:

CREATE PROCEDURE [uspOutputParameter]
    @Param int OUTPUT
AS BEGIN
   SET @Param = 1
END

DECLARE @err int
DECLARE @param int

EXECUTE @err = uspOutputParameter @Param OUTPUT
IF @err = 0 BEGIN
    PRINT 'OK'
    PRINT @Param
    END
ELSE BEGIN
    PRINT 'Error'
END

具有结果集的存储过程:

CREATE PROCEDURE [uspResultSet]
AS BEGIN
   SELECT 1 AS Result
END

CREATE TABLE #Temp (Result int)
INSERT INTO #Temp (Result)
EXECUTE uspResultSet

SELECT * 
FROM #Temp

答案 1 :(得分:1)

佐罗夫的解释不太正确。存储过程可以返回值。这些值是整数。没有显式的return,存储过程将失败并返回NULL

设置存储过程并被类型误导是完全有效的:

create procedure f
as begin
    return cast(2.3 as float)
end;

declare @f float;

exec @f = f;

print @f;

这返回什么?它返回2。为什么?返回值为整数。 SQL Server将2.3转换为整数并将其返回。这是在存储过程调用中得到的。

很可能您返回的值介于0和1之间,并且这些值被截断为0 -导致被零除错误。

佐罗夫的解决方案是正确的。使用输出参数。