我有以下函数“tickstodatetime”
CREATE FUNCTION [dbo].[TicksToDateTime] (@t bigint)
RETURNS datetime
WITH SCHEMABINDING
AS
-- converts the given datetime to .NET-compatible ticks
-- see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdatetimeclasstickstopic.asp
BEGIN
declare @result datetime
if (@t=0)
set @result = null
else
if (@t < 552877919999983334)
set @result = cast ('1753-1-1' as datetime)
else
if (@t=3155378975999999999)
set @result = cast ('9999-12-1' as datetime)
else
set @result = CAST((@t - 599266080000000000) / 10000000 / 24 / 60 / 60 AS datetime)
return @result
END
GO
在表的计算列中使用它:
[CallDateRaw] BIGINT NOT NULL,
[CallDate] AS ([dbo].[TicksToDateTime]([CallDateRaw])),
我现在尝试索引“calldate”列,如下所示:
Create Index ExternalCalls_CallDate2 ON [External.Call] (CallDate)
GO
但是索引失败,因为列是“不确定的”,我可以用以下方法确认函数也是不确定的:
select object_id('tickstodatetime')
select OBJECTPROPERTYEX(2127346643, 'IsDeterministic')
返回false。。
所以我的问题是为什么这个函数是“非确定性”的,我该如何使它具有确定性?从我在互联网上读到的,它只是说添加“与schemabinding”,但正如你所看到的,我已经添加了,它仍然不起作用。
我做错什么了?
2条答案
按热度按时间xggvc2p61#
使用
CAST
到/从旧的日期和时间数据类型是不确定的。使用CONVERT
从旧日期和时间到/从旧日期和时间的数据类型可以是确定性的,例如,如果使用的样式代码是确定性的或不是来自字符串的。您正在使用CAST
这里,所以不是。从确定性和非确定性函数:
以下函数并不总是确定性的,但当它们以确定性方式指定时,可以在索引视图或计算列的索引中使用。
在这种情况下,您需要使用
CONVERT
还有样式代码。例如,代替:您需要:
bybem2ql2#
正如@larnu极好答案的延伸:
我最终得到的功能是:
并通过