在this question的传统中,根据the documentation,如何使这个函数具有确定性:
ALTER FUNCTION [udf_DateTimeFromDataDtID]
(
@DATA_DT_ID int -- In form YYYYMMDD
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
RETURN CONVERT(datetime, CONVERT(varchar, @DATA_DT_ID))
END
或者这个(因为字符串/日期文字 - 是的,我也试过'1900-01-01'):
ALTER FUNCTION udf_CappedDate
(
@DateTimeIn datetime
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
IF @DateTimeIn < '1/1/1900'
RETURN '1/1/1900'
ELSE IF @DateTimeIn > '1/1/2100'
RETURN '1/1/2100'
RETURN @DateTimeIn
END
答案 0 :(得分:7)
BOL表示,如果指定了 style 参数,则CONVERT
确定性为日期时间。因此,如果您将第一个UDF更改为:
RETURN CONVERT(datetime, CONVERT(varchar, @DATA_DT_ID), 112)
如果我理解正确的文档, 应该是确定性的。
据推测,在第二个UDF中可以使用相同的技巧:
IF @DateTimeIn < CONVERT(datetime, '1/1/1900', 101)
RETURN CONVERT(datetime, '1/1/1900', 101)
我 确实 希望有一种方法可以在T-SQL中指定日期时间文字。
修改强>:
正如Arvo在评论中指出的那样(谢谢,Arvo),可以使用ODBC时间戳文字格式(即使使用OLE DB),因此上面的第二个函数可以更好地写为:
IF @DateTimeIn < {d '1900-01-01'}
RETURN {d '1900-01-01'}
...etc.
并且转换为datetime是在编译时而不是执行时完成的。请注意,日期的格式必须非常具体(请参阅Arvo's link to the datetime data type):
d YYYY-MM-DD
吨HH:MM:SS [.fff]
ts yyyy-mm-dd hh:mm:ss [.fff]
答案 1 :(得分:4)
来自您链接的文章:
要确定性,样式参数必须是常量。此外,小于或等于100的样式是不确定的,但样式20和21除外。大于100的样式是确定性的,样式106,107,109和113除外。
您需要在转换到日期时使用样式参数。
例如:
CONVERT(datetime, '2008-01-01', 121)
除非不要使用121 ......