2016-06-21 11 views
0

Ich habe eine kleine Funktion erstellt, die einige Datumsparameter akzeptiert und einen Projektstatus basierend auf einer von mir definierten Logik ausgibt.TSQL Scalar-Funktion

Ich versuche herauszufinden, wie ich die Funktion "ausbrechen" kann, sobald ein Status festgelegt wurde. In meiner Logik unten scheint es, dass es immer die dueDate überprüft und seinen Status setzt und überschreibt es dann selbst mit der folgenden Kontrolle.

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 

Sobald ein Status gesetzt wurde, muss ich aus dieser Funktion brechen, so der Status nicht wieder durch die Logik überschrieben wird, der ihm folgt.

Gibt es einen besseren Weg, damit umzugehen?

+3

decken Warum nicht nur 'return' aus den' IF' Aussagen stattdessen eine Variable der Einstellung? –

+0

warum nicht einfach 'RETURN' früh? oder verwenden Sie verschachtelte 'IF'-Blöcke, wenn Sie bei" nur 1 return statement "bleiben möchten – Jamiec

+0

oder' ELSE' verwenden ... –

Antwort

2

es Rewrite wie folgt:

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 

Sie können auch Gebrauch machen von IF-ELSE Block machen. Ich habe es umschreiben IF-ELSE zu verwenden, nur überprüfen, ob Ihre Logik noch gewährleistet ist oder nicht:

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

Wie über einen völlig anderen Ansatz hier? Skalarfunktionen sind schrecklich ineffizient und nicht sehr flexibel. Normalerweise ist es besser, eine Inline-Tabellenwertfunktion zu verwenden. Dies bedeutet, dass Sie eine einzelne SELECT-Anweisung verwenden müssen. Natürlich könnte Ihre ganze Serie verschachtelter IF-Anweisungen auf einige Case-Ausdrücke komprimiert werden. Dies ist viel einfacher zu pflegen, flexibler und leistungsfähiger.

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 

dies sollte Ihre Logik