标量函数是不确定的
Scalar function is non-deterministic
我想保留这个字段,但无法弄清楚为什么它是不确定的。
CREATE FUNCTION GetServiceMinutes
(
-- Add the parameters for the function here
@StartDate datetime,
@EndDate datetime
)
RETURNS int WITH SCHEMABINDING
AS
BEGIN
DECLARE @Result int
SET @StartDate = CASE WHEN DATEPART(HOUR, @StartDate) < 8 THEN DATEADD(DAY, DATEDIFF(DAY, 0, @StartDate), '08:00:00') ELSE @StartDate END
SET @EndDate = CASE WHEN DATEPART(HOUR, @EndDate) >= 17 THEN DATEADD(DAY, DATEDIFF(DAY, 0, @EndDate), '17:00:00') ELSE @EndDate END
SET @Result =
CASE WHEN DATEPART(DAY, @StartDate) != DATEPART(DAY, @EndDate) THEN 1000
WHEN DATEPART(HOUR, @EndDate) < 8 THEN 0
WHEN DATEPART(HOUR, @StartDate) >= 17 THEN 0
ELSE DATEDIFF(MINUTE, @StartDate, @EndDate)
END
RETURN @Result
END
GO
这个returns0
SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].GetServiceMinutes'), 'IsDeterministic')
使用 SQL 服务器 2017
正如我提到的,问题是您对(日期和)时间值的隐式转换。根据 documentation:
The following functions are not always deterministic, but can be used in indexed views or indexes on computed columns when they are specified in a deterministic manner.
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.
在你的函数中你有隐式转换,例如 '08:00:00'
到 datetime
。你需要明确:
CREATE FUNCTION dbo.GetServiceMinutes
(
-- Add the parameters for the function here
@StartDate datetime,
@EndDate datetime
)
RETURNS int WITH SCHEMABINDING
AS
BEGIN
DECLARE @Result int
SET @StartDate = CASE WHEN DATEPART(HOUR, @StartDate) < 8 THEN DATEADD(DAY, DATEDIFF(DAY, 0, @StartDate), CONVERT(datetime,'1900-01-01T08:00:00',126)) ELSE @StartDate END
SET @EndDate = CASE WHEN DATEPART(HOUR, @EndDate) >= 17 THEN DATEADD(DAY, DATEDIFF(DAY, 0, @EndDate), CONVERT(datetime,'1900-01-01T17:00:00',126)) ELSE @EndDate END
SET @Result =
CASE WHEN DATEPART(DAY, @StartDate) != DATEPART(DAY, @EndDate) THEN 1000
WHEN DATEPART(HOUR, @EndDate) < 8 THEN 0
WHEN DATEPART(HOUR, @StartDate) >= 17 THEN 0
ELSE DATEDIFF(MINUTE, @StartDate, @EndDate)
END
RETURN @Result
END
GO
SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].GetServiceMinutes'), 'IsDeterministic')
我想保留这个字段,但无法弄清楚为什么它是不确定的。
CREATE FUNCTION GetServiceMinutes
(
-- Add the parameters for the function here
@StartDate datetime,
@EndDate datetime
)
RETURNS int WITH SCHEMABINDING
AS
BEGIN
DECLARE @Result int
SET @StartDate = CASE WHEN DATEPART(HOUR, @StartDate) < 8 THEN DATEADD(DAY, DATEDIFF(DAY, 0, @StartDate), '08:00:00') ELSE @StartDate END
SET @EndDate = CASE WHEN DATEPART(HOUR, @EndDate) >= 17 THEN DATEADD(DAY, DATEDIFF(DAY, 0, @EndDate), '17:00:00') ELSE @EndDate END
SET @Result =
CASE WHEN DATEPART(DAY, @StartDate) != DATEPART(DAY, @EndDate) THEN 1000
WHEN DATEPART(HOUR, @EndDate) < 8 THEN 0
WHEN DATEPART(HOUR, @StartDate) >= 17 THEN 0
ELSE DATEDIFF(MINUTE, @StartDate, @EndDate)
END
RETURN @Result
END
GO
这个returns0
SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].GetServiceMinutes'), 'IsDeterministic')
使用 SQL 服务器 2017
正如我提到的,问题是您对(日期和)时间值的隐式转换。根据 documentation:
The following functions are not always deterministic, but can be used in indexed views or indexes on computed columns when they are specified in a deterministic manner.
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.
在你的函数中你有隐式转换,例如 '08:00:00'
到 datetime
。你需要明确:
CREATE FUNCTION dbo.GetServiceMinutes
(
-- Add the parameters for the function here
@StartDate datetime,
@EndDate datetime
)
RETURNS int WITH SCHEMABINDING
AS
BEGIN
DECLARE @Result int
SET @StartDate = CASE WHEN DATEPART(HOUR, @StartDate) < 8 THEN DATEADD(DAY, DATEDIFF(DAY, 0, @StartDate), CONVERT(datetime,'1900-01-01T08:00:00',126)) ELSE @StartDate END
SET @EndDate = CASE WHEN DATEPART(HOUR, @EndDate) >= 17 THEN DATEADD(DAY, DATEDIFF(DAY, 0, @EndDate), CONVERT(datetime,'1900-01-01T17:00:00',126)) ELSE @EndDate END
SET @Result =
CASE WHEN DATEPART(DAY, @StartDate) != DATEPART(DAY, @EndDate) THEN 1000
WHEN DATEPART(HOUR, @EndDate) < 8 THEN 0
WHEN DATEPART(HOUR, @StartDate) >= 17 THEN 0
ELSE DATEDIFF(MINUTE, @StartDate, @EndDate)
END
RETURN @Result
END
GO
SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].GetServiceMinutes'), 'IsDeterministic')