2016-06-21 50 views
0

我創建了一個小函數,該函數需要幾個日期參數,並根據我定義的某些邏輯輸出項目狀態。TSQL標量函數

我想弄清楚如何一旦狀態已經設置,我可以「突破」的功能。在我的邏輯下面,它似乎總是要檢查dueDate並設置它的狀態,然後用下面的檢查覆蓋它自己。

ALTER FUNCTION [dbo].[Fetch_TaskStatus] 
(
    -- Add the parameters for the function here 
    @startDate DATE = NULL, 
    @dueDate DATE = NULL, 
    @completionDate DATE = NULL 
) 
RETURNS varchar(100) 
AS 
BEGIN 
    -- Declare the return variable here 
    DECLARE @status varchar(100); 

    -- Declare our current date 
    DECLARE @now DATE = GETUTCDATE(); 

    -- Logic 
    -- If our start date and completion date are missing.. 
    IF(@startDate IS NULL AND @completionDate IS NULL) 
     BEGIN 

      -- If our due date is past the current date, its past due 
      IF(@dueDate < @now) 
      BEGIN 
       SET @status = 'Past Due'; 
      END 

      -- We have a start date but the task has not been started. 
      SET @status = 'Inactive'; 

     END 

     -- If we have a start date and no completion date 
    IF(@startDate IS NOT NULL AND @completionDate IS NULL) 
     BEGIN 

      -- Are we past due? 
      IF(@dueDate < @now) 
       BEGIN 
        SET @status = 'Past Due' 
       END 

      -- We are not past due, must be in progress 
      SET @status = 'In Progress' 

     END 

    -- If we have a start date and a completion date 
    IF(@startDate IS NOT NULL AND @completionDate IS NOT NULL) 

     BEGIN 
      -- We have started and completed our task 
      SET @status = 'Complete' 
     END 

    -- Return the result of the function 
    RETURN @status 

END 

一旦設置了狀態,我需要跳出此功能,以便狀態不會被其後面的邏輯再次覆蓋。

有沒有更好的方法來處理這個問題?

+3

爲什麼不'從'IF'語句中,而不是設置變量的RETURN'? –

+0

爲什麼不僅僅是'返回'早?或者如果你想堅持「只有1個返回語句」 – Jamiec

+0

或使用'ELSE',則使用嵌套的'IF'塊 –

回答

2

如下重寫它:

ALTER FUNCTION [dbo].[Fetch_TaskStatus] 
(
-- Add the parameters for the function here 
@startDate DATE = NULL, 
@dueDate DATE = NULL, 
@completionDate DATE = NULL 
) 
RETURNS varchar(100) 
AS 
BEGIN 
-- Declare the return variable here 
DECLARE @status varchar(100); 

-- Declare our current date 
DECLARE @now DATE = GETUTCDATE(); 

-- Logic 
-- If our start date and completion date are missing.. 
IF(@startDate IS NULL AND @completionDate IS NULL) 
    BEGIN 

     -- If our due date is past the current date, its past due 
     IF(@dueDate < @now) 
     BEGIN 
      RETURN 'Past Due'; 

     END 

     -- We have a start date but the task has not been started. 
      RETURN 'Inactive'; 

    END 

    -- If we have a start date and no completion date 
IF(@startDate IS NOT NULL AND @completionDate IS NULL) 
    BEGIN 

     -- Are we past due? 
     IF(@dueDate < @now) 
      BEGIN 
      RETURN 'Past Due' 

      END 

     -- We are not past due, must be in progress 
      RETURN 'In Progress' 

    END 

-- If we have a start date and a completion date 
IF(@startDate IS NOT NULL AND @completionDate IS NOT NULL) 

    BEGIN 
     -- We have started and completed our task 
      RETURN 'Complete' 
    END 

-- Return the result of the function 
RETURN 'Unknown'; 

END 

您還可以使用IF-ELSE塊。我已經使用過IF-ELSE重寫一遍,只是檢查,如果你的邏輯,但還是不能保證:

CREATE FUNCTION [dbo].[Fetch_TaskStatus] 
    (
     -- Add the parameters for the function here 
     @startDate DATE = NULL , 
     @dueDate DATE = NULL , 
     @completionDate DATE = NULL 
    ) 
RETURNS VARCHAR(100) 
AS 
    BEGIN 

-- Declare our current date 
     DECLARE @now DATE = GETUTCDATE(); 

-- Logic 
-- If our start date and completion date are missing.. 
     IF (@startDate IS NULL 
      AND @completionDate IS NULL 
      ) 
      BEGIN 
     -- If our due date is past the current date, its past due 
       IF (@dueDate < @now) 
        RETURN 'Past Due'; 
       ELSE 
         -- We have a start date but the task has not been started. 
        RETURN 'Inactive'; 
      END; 

    -- If we have a start date and no completion date 
     IF (@startDate IS NOT NULL 
      AND @completionDate IS NULL 
      ) 
      BEGIN 
      -- Are we past due? 
       IF (@dueDate < @now) 
        RETURN 'Past Due'; 
       ELSE 
         -- We are not past due, must be in progress 
        RETURN 'In Progress'; 
      END; 

-- If we have a start date and a completion date 
     IF (@startDate IS NOT NULL 
      AND @completionDate IS NOT NULL 
      ) 
      -- We have started and completed our task 
      RETURN 'Complete'; 

     -- Return the result of the function 
     RETURN 'Unknown'; 
    END; 
0

如何在這裏完全不同的方法?標量函數的效率非常低,不夠靈活。通常更好的方法是使用內聯表值函數。這意味着您必須使用單個選擇語句。當然,你的整個系列的嵌套IF語句可以被壓縮成幾個case表達式。這要簡單得多,維護更靈活,性能更好。

ALTER FUNCTION [dbo].[Fetch_TaskStatus] 
(
    @startDate DATE = NULL, 
    @dueDate DATE = NULL, 
    @completionDate DATE = NULL 
) 
RETURNS table as return 
    select TaskStatus = 
     Case 
      WHEN @startDate IS NULL AND @completionDate IS NULL then 
       Case when @dueDate < GETUTCDATE() then 'Past Due' else 'Inactive' end 

      WHEN @startDate IS NOT NULL AND @completionDate IS NULL then 
       Case when @dueDate < GETUTCDATE() then 'Past Due' else 'In Progress' end 
      WHEN @startDate IS NOT NULL AND @completionDate IS NOT NULL then 'Complete' 
     END 
0
CREATE FUNCTION [dbo].[Fetch_TaskStatus] (
    -- Add the parameters for the function here 
    @startDate DATE = NULL, 
    @dueDate DATE = NULL, 
    @completionDate DATE = NULL 
    ) 
RETURNS VARCHAR(100) 
AS 
    BEGIN 
    -- Declare our current date 
     DECLARE @now DATE = GETUTCDATE(); 

     RETURN CASE WHEN @startDate IS NOT NULL AND @completionDate IS NOT NULL THEN 'Complete' 
        WHEN @dueDate < @now THEN 'Past Due' 
        WHEN @startDate IS NOT NULL AND @completionDate IS NULL THEN 'In Progress' 
        WHEN @startDate IS NULL AND @completionDate IS NULL THEN 'Inactive' 
        END 
    END 

這應該包括你的邏輯