-1

我有 2 个计算列,[StartTime]并且[EndTime]

[StartTime][EndTime]是通过使用[Week][Year]列的公式计算的。

现在我需要另一个计算列,[Status]它是使用前两个计算的。但是当我尝试在公式中使用其中一个时,它给了我一个公式错误[Status]

我真的需要这个工作,因为我别无选择。但这甚至可能吗?

给你 -1 先生:

(case when [IsVOR]=(1) then 'VOR' 
      when [MarkedAsCompleteOn] IS NULL AND [Year]<datepart(year,getdate()) then 'Overdue' 
      when [MarkedAsCompleteOn] IS NULL AND [Year]>datepart(year,getdate()) then 'Not Due' 
      when [MarkedAsCompleteOn] IS NULL AND [Year]=datepart(year,getdate()) AND [Week]<datepart(iso_week,getdate()) then 'Overdue' 
      when [MarkedAsCompleteOn] IS NULL AND [Year]=datepart(year,getdate()) AND [Week]=datepart(iso_week,getdate()) then 'Due' 
      when [MarkedAsCompleteOn] IS NULL AND [Year]=datepart(year,getdate()) AND [Week]>datepart(iso_week,getdate()) then 'Not Due' 
      when [MarkedAsCompleteOn] IS NOT NULL AND [Year]<datepart(year,[MarkedAsCompleteOn]) then 'Late' 
      when [MarkedAsCompleteOn] IS NOT NULL AND [Year]>datepart(year,[MarkedAsCompleteOn]) then 'Early' 
      when [MarkedAsCompleteOn] IS NOT NULL AND [Year]=datepart(year,[MarkedAsCompleteOn]) AND [Week]<datepart(iso_week,[MarkedAsCompleteOn]) then 'Late' 
      when [MarkedAsCompleteOn] IS NOT NULL AND [Year]=datepart(year,[MarkedAsCompleteOn]) AND [Week]=datepart(iso_week,[MarkedAsCompleteOn]) then 'On Time' 
      when [MarkedAsCompleteOn] IS NOT NULL AND [MarkedAsCompleteOn]<[AllocatedTimeStart] then 'Early'  end)

它的最后一部分导致错误:

[MarkedAsCompleteOn]<[AllocatedTimeStart] then 'Early'

错误是通用的:

- Error validating the formula for column 'Status'.
4

2 回答 2

0

不可以。一个计算列不能基于不同的计算列。这有一个特定的错误(1759):

不允许在另一个计算列定义中使用表“%s”中的计算列“%s”。

您可以基于表创建一个视图,并在视图定义中执行第二轮计算。无论您随后对视图执行所有活动(如果需要,添加触发器),还是仅将其用于查找,都是您需要做出的设计决策。

当然,如果您添加了使用视图的想法,您可以使用 Common Table 表达式构建多个(不仅仅是 2 个)计算层。

您确实失去了使计算列持久化的能力,除非视图有资格成为索引视图 - 在这种情况下这并不重要,因为它似乎是基于日期计算的,所以无论如何可能都不能持久化。

于 2013-01-02T10:57:23.183 回答
0

我最终找到了自己的解决方案,通过使用 a function,这使我的生产应用程序无需任何更改即可运行。

USE [DBNAME]
GO
/****** Object:  UserDefinedFunction [dbo].[GetStatus]    Script Date: 01/02/2013 11:08:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GetStatus](@CompletedOn DATETIME, @Year INT, @Week INT)
RETURNS NVARCHAR(MAX)
AS BEGIN
    DECLARE @CurrentDate DATETIME
    DECLARE @StartTime DATETIME
    DECLARE @EndTime DATETIME
    DECLARE @Status NVARCHAR(MAX)

    SET @CurrentDate = GETDATE()
    SET @StartTime = (dateadd(week,@Week-(1),dateadd(day,(-1),dateadd(week,datediff(week,(0),CONVERT([varchar](4),@Year,(0))+'-01-01'),(1)))))
    SET @EndTime = (dateadd(week,@Week-(1),dateadd(day,(-1),dateadd(week,datediff(week,(0),CONVERT([varchar](4),@Year,(0))+'-01-01'),(8)))))

    SET @Status = '-'
    IF(@CompletedOn IS NULL)
        BEGIN
            IF(@CurrentDate < @StartTime)
                SET @Status = 'Not Due'
            IF(@CurrentDate > @StartTime AND @CurrentDate < @EndTime)
                SET @Status = 'Due'
            IF(@CurrentDate > @EndTime)
                SET @Status = 'Overdue'
        END
    ELSE
        BEGIN
            IF(@CompletedOn < @StartTime)
                SET @Status = 'Early'
            IF(@CompletedOn > @EndTime)
                SET @Status = 'Late'
            ELSE
                SET @Status = 'On Time'
        END

    RETURN @Status
END

status现场我输入了公式:

([dbo].[GetStatus]([MarkedAsCompleteOn],[Year],[Week]))

这是我的第一次functionsql server所以它可能不是最佳的。

于 2013-01-02T11:55:52.753 回答