5

this question传统,在the documentation光,一个人如何使这个功能确定性:如何从varchar转换为datetime确定性?

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 

回答

6

BOL说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的日期时间文字的方式。

编辑

正如评论指出的帕特(谢谢,帕特)时,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]

2

从你链接的文章:

要确定的,样式参数必须是一个常数。此外,小于或等于100的样式是不确定的,除了样式20和21.样式大于100是确定性的,除了样式106,107,109和113.

您需要使用样式参数在转换为日期时间。

例如:

CONVERT(datetime, '2008-01-01', 121) 

除了不使用121 ...

+0

那么没有字面日期作为UDF字符串没有被CONVERTed? – 2008-11-21 20:55:27

+0

如果字符串隐式转换为日期,那么这些转换缺乏“常量”风格,并且会使该函数不确定。 – 2008-11-21 21:08:16