我有一个表格,在其列的列中有两列INT
类型,它们被称为:
ExpirationMonth
和
ExpirationYear
我想在此表中添加一个新列,其值将根据ExpirationMonth
和ExpirationYear
的值进行计算。所以这个列将是一个计算列。
为此,我创建了一个用户定义的标量函数,该函数根据ExpirationMonth
和ExpirationYear
的值计算此列的值。该功能的定义如下:
CREATE FUNCTION [dbo].[IsExpired]
(
@ExpirationMonth INT,
@ExpirationYear INT
)
RETURNS BIT
AS
BEGIN
DECLARE @Today DATE = GETDATE()
DECLARE @PreviousMonth INT = MONTH(@today)-1
DECLARE @CurrentYear INT = YEAR(@today)
DECLARE @IsExpired BIT = 0
IF(@ExpirationYear<@CurrentYear OR
(@ExpirationYear=@CurrentYear AND @ExpirationMonth<=@PreviousMonth))
SET @IsExpired = 1
RETURN @IsExpired
END
最初,我尝试按以下方式添加列:
ALTER Table_Name
ADD IsExpired AS [dbo].[IsExpired]([ExpirationMonth], [ExpirationYear]) PERSISTED
我收到以下错误:
计算专栏&#39; IsExpired&#39;在表格&#39; Table_Name&#39;不能坚持下去 因为该列是非确定性的。
我从上面的语句中删除了PERSISTED
,然后再次运行它。然后我注意到该列已添加了预期值。
我的问题是,如果可以的话,我怎样才能保留此列?
我意识到这个错误的原因是在GETDATE
函数中使用了IsExpired
函数。由于GETDATE
不具有确定性,IsExpired
不具有确定性。
但是,我不知道如何使这个函数IsExpired
成为确定性的,并且因此将计算列定义为持久化(如果可能的话)。
请您告诉我这是否可能,如果可能,我该怎么办呢。
答案 0 :(得分:2)
该值是不确定的,因为它取决于当前日期。您不能保留其值可能随时间变化的计算列。
有关确定性函数的详细信息,请参阅MSDN上的this article。
答案 1 :(得分:0)
我建议在视图中进行操作
SELECT * INTO yourTable
FROM (VALUES(2015,1),(2015,2),(2015,3),(2015,4),(2015,5),(2015,6)) AS A(ExpirationYear,ExpirationMonth);
GO
CREATE VIEW vw_Expiration
AS
SELECT ExpirationYear,
ExpirationMonth,
CASE
WHEN ExpirationYear < YEAR(GETDATE()) OR
(ExpirationYear = YEAR(GETDATE()) AND ExpirationMonth <= MONTH(GETDATE()))
THEN 1
ELSE 0
END AS IsExpired
FROM yourTable;
GO
SELECT *
FROM vw_Expiration
结果:
ExpirationYear ExpirationMonth IsExpired
-------------- --------------- -----------
2015 1 1
2015 2 1
2015 3 1
2015 4 1
2015 5 0
2015 6 0