不能坚持计算列 - 不确定性(Cannot persist computed column - no

2019-07-17 18:59发布

我有这个功能的计算列:

CREATE FUNCTION [dbo].[GetAllocatedStartTime](@Year INT, @Week INT)
RETURNS DATETIME

WITH schemabinding
AS BEGIN
    RETURN dateadd(week,@Week-(1),dateadd(day,(-1),dateadd(week,datediff(week,(0),CONVERT([varchar](4),@Year,(0))+'-01-01'),(1))))
END

GO

我加入了WITH schemabinding希望它将使确定性,所以我可以坚持它。 它应该是作为两个输入[Week][Year]总是会产生相同的结果。

确切的错误是:

在表“Tmp_Bookings”计算列“AllocatedTimeStart”不能持久,因为该列具有不确定性。

我使用这个公式列:

([dbo].[GetAllocatedStartTime]([Year],[Week]))

而列DEFS:

[Week] [int] NOT NULL,
[Year] [int] NOT NULL,
[AllocatedTimeStart]  AS ([dbo].[GetAllocatedStartTime]([Year],[Week])),

有任何想法吗?

编辑:

改线:

RETURN dateadd(week,@Week-(1),dateadd(day,(-1),dateadd(week,datediff(week,(0),CONVERT(datetime,CONVERT([varchar](4),@Year,(0))+'0101',112)),(1))))

但现在我得到一个错误说该列的公式是无效的。 虽然功能节省了罚款。

编辑2:

我已经证明我在做什么(或者至少我试过)。 没有什么额外真的。 因为它说加上式REF先前函数(原始) [dbo].AllocatedStartDate(...)的列中,它的工作,但没有持续,则说这是不确定性的。 因此,根据建议我换的功能,用新的代码替换转换部分,因此函数现在看起来像:

FUNCTION [dbo].[GetSTime](@Year INT, @Week INT)

RETURNS DATETIME
WITH schemabinding
AS BEGIN
    RETURN dateadd(week,@Week-(1),dateadd(day,(-1),dateadd(week,datediff(week,(0),CONVERT(datetime,CONVERT([varchar](4),@Year,(0))+'0101',112)),(1))))
END

然后,我在计算领域的尝试过同样的公式(([dbo].[GetAllocatedStartTime]([Year],[Week]))) ... ...,它拒绝公式,表示其无效...这是奇怪的公式是相同的,所以它必须做某种改变的功能的检查,并发现是无效的,这也是奇怪,因为我做了一个简单的SELECT dbo.GetAllocatedStartTime(2012,13)和它的工作。 ..

所以,是的,我很困惑,我从来没有见过SqlFiddle没关系使用它。 不过说真的,没有什么比我刚才说了。

Answer 1:

CONVERT([varchar](4),@Year,(0))+'-01-01'被传递给一个DATEDIFF呼叫,在日期的预期,迫使发生的隐式转换的位置。

从规则的确定性函数 :

CAST

确定性除非使用datetimesmalldatetimesql_variant

CONVERT

除非确定这些条件之一存在:

...

源或目标类型是datetimesmalldatetime ,其他源或目标类型为字符串,并且指定了不确定的样式。 要确定的,样式参数必须是一个常数。 此外,样式小于或等于100是确定性的,除了样式20和21大于100的样式是确定性的,除了样式106,107,109和113。

好了,你打电话都不是,但你依靠一个隐含的转换,这是我希望见到像CAST 。 而不是靠这个,我会切换到使用CONVERT并给予确定性风格参数。

所以,我会怎么做: CONVERT(datetime,CONVERT([varchar](4),@Year,(0))+'0101',112)在它的位置。 这样做之后,函数本身变得确定性



文章来源: Cannot persist computed column - not deterministic