Cad*_*oux 7 sql sql-server sql-server-2005 deterministic user-defined-functions
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
Run Code Online (Sandbox Code Playgroud)
或者这个(因为字符串/日期文字 - 是的,我也试过'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
Run Code Online (Sandbox Code Playgroud)
如果指定了样式参数,BOL表示对日期时间CONVERT 具有确定性.因此,如果您将第一个UDF更改为:
RETURN CONVERT(datetime, CONVERT(varchar, @DATA_DT_ID), 112)
Run Code Online (Sandbox Code Playgroud)
如果我正确理解文档,那么它应该是确定性的.
据推测,可以在第二个UDF中使用相同的技巧:
IF @DateTimeIn < CONVERT(datetime, '1/1/1900', 101)
RETURN CONVERT(datetime, '1/1/1900', 101)
Run Code Online (Sandbox Code Playgroud)
我真的希望有一种方法可以在T-SQL中指定日期时间文字.
编辑:
正如Arvo在评论中所指出的那样(感谢 Arvo),可以使用ODBC时间戳文字格式(即使使用OLE DB),因此上面的第二个函数可以更好地编写为:
IF @DateTimeIn < {d '1900-01-01'}
RETURN {d '1900-01-01'}
...etc.
Run Code Online (Sandbox Code Playgroud)
转换为datetime是在编译时而不是执行时完成的.请注意,日期的格式必须非常具体(请参阅Arvo指向日期时间数据类型的链接):
d yyyy-mm-dd
t hh:mm:ss [.fff]
ts yyyy-mm-dd hh:mm:ss [.fff]
从您链接的文章中:
要确定性,样式参数必须是常量。此外,小于或等于 100 的样式是不确定的,但样式 20 和 21 除外。大于 100 的样式是确定的,但样式 106、107、109 和 113 除外。
您需要在转换为日期时间时使用样式参数。
例如:
CONVERT(datetime, '2008-01-01', 121)
Run Code Online (Sandbox Code Playgroud)
除了不要使用 121 ...