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