use*_*er1 2 sql sql-server function calculated-columns sql-function
我有以下功能“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
Run Code Online (Sandbox Code Playgroud)
并在表的计算列中使用它:
[CallDateRaw] BIGINT NOT NULL,
[CallDate] AS ([dbo].[TicksToDateTime]([CallDateRaw])),
Run Code Online (Sandbox Code Playgroud)
我现在正在尝试索引“CallDate”列,如下所示:
Create Index ExternalCalls_CallDate2 ON [External.Call] (CallDate)
GO
Run Code Online (Sandbox Code Playgroud)
但是索引失败,因为该列是“非确定性的”,我可以通过以下方式确认该函数也是非确定性的:
select object_id('tickstodatetime')
select OBJECTPROPERTYEX(2127346643, 'IsDeterministic')
Run Code Online (Sandbox Code Playgroud)
哪个返回错误..
所以我的问题是为什么这个函数是“非确定性的”,我如何使它具有确定性?从我在互联网上阅读的内容来看,它只是说添加“With SchemaBinding”,但正如您所看到的,我已经添加了它,但它仍然不起作用。
我究竟做错了什么?
使用CAST旧日期和时间数据类型是不确定的。使用CONVERT旧的日期和时间数据类型可以是确定性的,例如,如果使用确定性或不是来自字符串的样式代码。你在CAST这里使用,所以它不是。
以下函数并不总是确定性的,但当它们以确定性方式指定时,可以在索引视图或计算列的索引中使用。
Run Code Online (Sandbox Code Playgroud)Function Comments all aggregate functions All aggregate functions are deterministic unless they are specified with the OVER and ORDER BY clauses. For a list of these functions, see Aggregate Functions (Transact-SQL). CAST Deterministic unless used with datetime, smalldatetime, or sql_variant. CONVERT Deterministic unless one of these conditions exists: Source type is sql_variant. Target type is sql_variant and its source type is nondeterministic. Source or target type is datetime or smalldatetime, the other source or target type is a character string, and a nondeterministic style is specified. To be deterministic, the style parameter must be a constant. Additionally, styles less than or equal to 100 are nondeterministic, except for styles 20 and 21. Styles greater than 100 are deterministic, except for styles 106, 107, 109 and 113.
在这种情况下,您需要使用CONVERT和样式代码。因此,例如,而不是:
set @result = cast ('1753-1-1' as datetime)
Run Code Online (Sandbox Code Playgroud)
您需要执行以下操作:
SET @Result = CONVERT(datetime, '17530101',112);
Run Code Online (Sandbox Code Playgroud)