2

I made a user-define function for business hours calculation.

This is my UDF.

CREATE FUNCTION  fn_GetBusinessHour (@date datetime, @addHours int)
RETURNS datetime
AS
BEGIN 
    DECLARE @CalcuatedDate datetime;
    DECLARE @addDayCount int, @addHourCount int, @addMinCount int;

    SET @addDayCount = @addHours / 8.5;
    SET @addHourCount = @addHours - (@addDayCount * 8.5);
    SET @addMinCount =  @addHours - (@addDayCount * 8.5) - @addHourCount;

    IF(@addDayCount != 0) 
        SET @CalcuatedDate = DATEADD(DD, @addDayCount, @date); 

    SET @CalcuatedDate = DATEADD(HH, @addHourCount, @CalcuatedDate);

    IF(@addMinCount != 0) 
        SET @CalcuatedDate = DATEADD(MM, @addMinCount, @CalcuatedDate); 

    RETURN @CalcuatedDate;
END

When I test using following statement,

SELECT dbo.fn_GetBusinessHour(GETDATE(), 40)

It shows proper result.

However, I use my function like this,

SELECT TicketID
     , DateTimeLogged --Type: Datetime
     , Priority       --Type: int
     , [dbo].[fn_GetBusinessHour](DateTimeLogged, Priority)
  FROM TicketHeader

the result shows only NULL value.

TicketID    DateTimeLogged  Priority    (No column name)
1   2011-07-04 11:26:19.510     30  NULL
2   2011-07-04 13:58:45.683     30  NULL
3   2011-07-05 10:09:16.923     10  NULL
4   2011-07-05 13:13:30.237     30  NULL
5   2011-07-05 16:50:34.033     20  NULL

I tried CONVERT because it worked when I give a value 40 but it also shows null values.

SELECT TicketID
         , DateTimeLogged --Type: Datetime
         , Priority       --Type: int
         , [dbo].[fn_GetBusinessHour](DateTimeLogged, CONVERT(int, Priority))
      FROM TicketHeader

How can I fix this to work my UDF? Why this thing happen? I cannot understand what is different between Priority and 40.

Thank you in advance.

1 Answer 1

3

For values of priority > 8.5, this seems to work fine for me:

DECLARE @t TABLE(TicketID INT, DateTImeLogged DATETIME, Priority INT);

INSERT @t SELECT 1,'20110704 11:26:19.510',30
UNION ALL SELECT 2,'20110704 13:58:45.683',30
UNION ALL SELECT 3,'20110705 10:09:16.923',10
UNION ALL SELECT 4,'20110705 13:13:30.237',30
UNION ALL SELECT 5,'20110705 16:50:34.033',20;

SELECT TicketID
     , DateTimeLogged --Type: Datetime
     , Priority       --Type: int
     , [dbo].[fn_GetBusinessHour](DateTimeLogged, Priority)
  FROM @t;

Yields:

TicketID  DateTimeLogged           Priority  (No column name)
--------  -----------------------  --------  -----------------------
1         2011-07-04 11:26:19.510  30        2011-07-07 15:26:19.510
2         2011-07-04 13:58:45.683  30        2011-07-07 17:58:45.683
3         2011-07-05 10:09:16.923  10        2011-07-06 11:09:16.923
4         2011-07-05 13:13:30.237  30        2011-07-08 17:13:30.237
5         2011-07-05 16:50:34.033  20        2011-07-07 19:50:34.033

If I add another row with a Priority < 8.5, e.g.:

INSERT @t SELECT 6,'20110705 13:13:30.237',5;

Then this row is added to the result:

TicketID  DateTimeLogged           Priority  (No column name)
--------  -----------------------  --------  -----------------------
6         2011-07-05 13:13:30.237  5         NULL

In other words, the function will output NULL if the function logic leaves @CalculatedDate unassigned, which will happen if @addDayCount = 0. In the function you say:

IF(@addDayCount != 0) 
    SET @CalcuatedDate = DATEADD(DD, @addDayCount, @date); 

Since @addDayCount is an INT, try this:

DECLARE @addDayCount INT;
SET @addDayCount = 5 / 8.5;
SELECT @addDayCount;

Result:

0

So because @CalculatedDate isn't assigned a value initially, all of the following DATEADD operations are performing DATEADD(interval, number, NULL) which still yields NULL.

So perhaps you need to use a different data type for the variables in the function...

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much @aaronb. Finally I knew it. I add one line DECLARE CalcuatedDate = date. It prevent DATEADD(interval, number, NULL). Thank you again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.