Хранимая процедура делится на ноль, несмотря на ненулевые результаты - PullRequest
0 голосов
/ 09 мая 2019

У меня есть хранимая процедура, которая вызывает две другие хранимые процедуры, которые возвращают правильные значения и не равны нулю.

Я перепробовал все, что смог найти на эту тему

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 как ноль Тем не менее, в результатах я вижу, что он запросил обе таблицы и вернул ненулевые значения 2,22000 для totHrs и значение 5,25 для estHrs

Ответы [ 2 ]

6 голосов
/ 09 мая 2019

Переменные @estHrs и @totHrs содержат результаты выполнения ваших вложенных хранимых процедур. Если они выполняются без ошибок, эти результаты будут 0, и это является причиной вашей Divide by zero ошибки.

Важно сделать различие между результатом выполнения хранимой процедуры и набором результатов, который возвращает эта процедура.

Если вы хотите вернуть одно значение из вашей хранимой процедуры, используйте выходной параметр . Если ваша процедура возвращает набор результатов, вы можете вставить этот результат в таблицу и выбрать соответствующие значения из этой таблицы.

Хранимая процедура с выходным параметром:

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 голос
/ 09 мая 2019

Объяснение Жорова не совсем верно.Хранимые процедуры могут возвращать значения.Эти значения являются целыми числами.Без явного 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 - вызывая ошибку деления на ноль.

Решение Жорова верное.Используйте выходные параметры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...