2012-06-25 51 views
2

我爲營業時間計算做了一個用戶定義函數。在SELECT語句中使用UDF

這是我的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 

當我測試使用下面的語句,

SELECT dbo.fn_GetBusinessHour(GETDATE(), 40) 

它顯示了正確的結果。

但是,我用我的功能就是這樣,

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

結果僅顯示NULL值。

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 

我試過CONVERT,因爲它在我給出值40時工作,但它也顯示空值。

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

我該如何解決這個問題來解決我的UDF問題? 這件事發生的原因是什麼? 我不明白優先級和40之間有什麼不同。

謝謝你提前。

回答

3

對於優先級> 8.5的值,這似乎爲我工作的罰款:

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; 

產量:

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 

如果我添加了優先< 8.5,如另一行:

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

然後將此行添加到結果中:

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

換句話說,如果功能邏輯離開@CalculatedDate未分配的功能將輸出NULL,如果@addDayCount = 0的功能,你說哪個會發生:

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

由於@addDayCount是一個INT,試試這個:

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

結果:

0 

因此,因爲@CalculatedDate最初未分配一個值,所有以下DATEADD操作都在執行DATEADD(interval,number,NULL),該值仍然爲NULL。

因此,也許你需要使用不同的數據類型的功能變量...

+0

非常感謝你@aaronb。最後我知道了。我添加一行DECLARE CalcuatedDate = date。它防止DATEADD(間隔,數字,NULL)。再次感謝你。 – ShootingStar