Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 设计中的计算列是否可以引用sql server中的其他列?_Database_Sql Server 2008_Tsql_Calculated Columns - Fatal编程技术网

Database 设计中的计算列是否可以引用sql server中的其他列?

Database 设计中的计算列是否可以引用sql server中的其他列?,database,sql-server-2008,tsql,calculated-columns,Database,Sql Server 2008,Tsql,Calculated Columns,我有两个计算列,[StartTime]和[EndTime] [StartTime]和[EndTime]通过使用[Week]和[Year]列的公式进行计算 现在我需要另一个计算列,[Status],它是使用前两个列计算的。但是当我试图在[Status] 我真的需要这个工作,因为我别无选择。但这有可能吗 给你,先生-1: (case when [IsVOR]=(1) then 'VOR' when [MarkedAsCompleteOn] IS NULL AND [Year]<d

我有两个计算列,
[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)

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

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

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

当然,如果您添加了使用视图的想法,则可以通过使用公共表表达式构建多个(而不仅仅是2个)计算层


除非该视图符合成为索引视图的条件,否则您确实无法使计算列持久化。在本例中,这并不重要,因为它似乎基于日期计算,因此可能无论如何都不可持久化。

我最终通过使用
函数找到了自己的解决方案,这使我的生产应用程序保持运行,没有任何更改

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

这是我在
sql server
中的第一个
函数,因此它可能不是最佳的。

-1用于不发布查询和错误。可能不太理想,但您始终可以根据周和年列计算状态…复制意大利面…是的,有可能…@rene这是我目前正在做的事情,但它会导致准确性问题。例如,12月31日显示为第53周,如果我可以使用日期来限制,这将非常容易。12月31日显示为哪一周可能会重复?毕竟一年中有超过52周的时间。不幸的是,我有一个应用程序正在生产,它依赖于这个表,并且[状态]正常工作。目前,它给出了不正确的结果,所以我需要在适当的地方修复。我正在试验一个函数,所以希望它能成功。我只是想知道是否可以在计算字段的公式中声明变量?@MuhammadA-您可以重命名表,然后使用表的原始名称创建一个视图。如果视图是可更新的(或者,如果需要,您可以创建所需的触发器),那么原始应用程序应该不知道幕后的更改。这就是我说的反对观点进行所有活动时含糊其辞的意思。(这也是我不喜欢人们在数据库对象中使用匈牙利式前缀的原因之一——你不应该知道或关心你是在处理一个表还是一个视图)谢谢你的建议Damien,但我的解决方案是有效的,目前我觉得,“如果它没有损坏,就不要修复它”。
- Error validating the formula for column 'Status'.
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
([dbo].[GetStatus]([MarkedAsCompleteOn],[Year],[Week]))