Синтаксис вызова функции: выберите xxxxx ('2018.09.28 19:02:28', '2018-09-29 10:40:35') Функция выдает результат как 98 минут, правильный ответ - 160 минут.
Функциональная структура:
Create FUNCTION xxxxx (@LeadAssignTime DATETIME, @LeadContactTime DATETIME)
RETURNS VARCHAR(9)
AS
BEGIN
DECLARE @Temp BIGINT
SET @Temp=0
DECLARE @LeadAssignDay VARCHAR(9)
SET @LeadAssignDay = CONVERT(VARCHAR(9),@LeadAssignTime, 112)
DECLARE @LeadContactDay VARCHAR(9)
SET @LeadContactDay = CONVERT(VARCHAR(9),@LeadContactTime, 112)
DECLARE @StartTime VARCHAR(9)
SET @StartTime = CONVERT(VARCHAR(9),@LeadAssignTime, 108)
DECLARE @FinishTime VARCHAR(9)
SET @FinishTime = CONVERT(VARCHAR(9),@LeadContactTime, 108)
DECLARE @WorkStart VARCHAR(9)
SET @WorkStart = '08:00:00'
DECLARE @WorkFinish VARCHAR(9)
SET @WorkFinish = '18:00:00'
IF (@StartTime<@WorkStart)
BEGIN
SET @StartTime = @WorkStart
END
IF (@FinishTime>@WorkFinish)
BEGIN
SET @FinishTime=@WorkFinish
END
DECLARE @CurrentDate VARCHAR(9)
SET @CurrentDate = CONVERT(VARCHAR(9),@LeadAssignTime, 112)
DECLARE @LastDate VARCHAR(9)
SET @LastDate = CONVERT(VARCHAR(9),@LeadContactTime, 112)
WHILE(@CurrentDate<=@LastDate)
BEGIN
IF (DATEPART(dw, @CurrentDate)!=1 )
BEGIN
IF (@CurrentDate!=@LeadAssignDay) AND (@CurrentDate!=@LeadContactDay)
BEGIN
SET @Temp = (@Temp + (8*60))
END
ELSE IF (@CurrentDate=@LeadAssignDay) AND (@CurrentDate!=@LeadContactDay)
BEGIN
SET @Temp = @Temp + DATEDIFF(MINUTE, @StartTime, @WorkFinish)
END
ELSE IF (@CurrentDate!=@LeadAssignDay) AND (@CurrentDate=@LeadContactDay)
BEGIN
SET @Temp = @Temp + DATEDIFF(MINUTE, @WorkStart, @FinishTime)
END
ELSE IF (@CurrentDate=@LeadAssignDay) AND (@CurrentDate=@LeadContactDay)
BEGIN
SET @Temp = DATEDIFF(MINUTE, @StartTime, @FinishTime)
END
END
SET @CurrentDate = CONVERT(VARCHAR(9),DATEADD(day, 1, @CurrentDate),112)
END
Return @TEMP
END
Я бы предостерегал вас от использования подобных скалярных функций. Они ужасно неэффективны и медлительны. Тогда добавление курсора внутрь - это бомба замедленного действия. Что вам действительно нужно, так это календарный стол. Это позволяет делать такие вещи на основе набора и предлагает гибкость таких вещей, как праздники, случайная необходимая суббота или даже неполные дни.


Вы проходите свой цикл дважды, но на первой итерации вы попадаете во второй блок IF и устанавливаете @temp равным -62
Во второй итерации вы попадаете в третий блок IF и вычисляете 160 для разницы между @WorkStart и @FinishTime, но затем это добавляется к значению, уже находящемуся в @Temp. 160-62 = 98.
Вам понадобится второй блок IF, чтобы перед выполнением этой логики проверить, не совпадает ли «время начала» с «концом работы».
(@CurrentDate=@LeadAssignDay) AND (@CurrentDate!=@LeadContactDay)
должен стать
(@CurrentDate=@LeadAssignDay) AND (@CurrentDate!=@LeadContactDay) AND ( @StartTime < @WorkFinish)
Я не проводил никаких проверок, кроме одного варианта использования. Обязательно проведите тщательное тестирование.
Я проведу еще несколько тестов.
Это то же самое, что рабочее время между двумя датами, на которые был задан вопрос и на который был дан ответ. Ваш код похож, но не совпадает. stackoverflow.com/questions/5274208/…