【问题标题】:Can a computed column in design reference another in sql server?设计中的计算列可以引用sql server中的另一个吗?
【发布时间】:2013-01-02 10:27:28
【问题描述】:

我有 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'.

【问题讨论】:

  • -1 表示未发布查询和错误。
  • 可能并不理想,但您始终可以根据周和年列计算状态....复制-意大利面...所以是的,有可能...
  • @rene 这就是我目前正在做的,但它会导致准确性问题。例如,12 月 31 日显示为第 53 周,如果我可以使用日期来限制,那就容易多了。
  • 12 月 31 日应该显示为哪一周?毕竟一年有超过 52 周。

标签: database sql-server-2008 tsql calculated-columns


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 不幸的是,我有一个生产中的应用程序依赖于这个表并且 [Status] 工作。目前它给出的结果不正确,所以我需要就地修复。我正在试验一个功能,所以希望这会奏效。我只是想知道是否可以在计算字段的公式中声明变量?
  • @MuhammadA - 您可以重命名表,然后使用表的原始名称创建视图。如果视图是可更新的(或者,如果需要,您可以创建所需的触发器),原始应用程序应该不知道幕后的这种变化。这就是我在谈到针对视图执行所有活动时模糊地指的内容。 (这也是我不喜欢人们在数据库对象中使用匈牙利风格前缀的原因之一——你不应该知道关心你是否正在处理一个表或视图)
  • 感谢您的建议 Damien,但我的解决方案有效,目前我觉得,“如果它没有损坏,请不要修复它”。
【解决方案2】:

我最终找到了自己的解决方案,通过使用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]))

这是我在sql server 中的第一个function,所以它可能不是最佳的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-23
    • 2019-12-25
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 2010-11-22
    • 1970-01-01
    相关资源
    最近更新 更多