2016-06-21 47 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 

这应该包括你的逻辑