Как сделать преобразования из varchar в datetime детерминированными? - PullRequest
7 голосов
/ 21 ноября 2008

В традиции этого вопроса и в свете документации , как сделать эту функцию детерминированной:

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

Ответы [ 2 ]

7 голосов
/ 21 ноября 2008

BOL говорит, что CONVERT является детерминированным с датами и временем, если указан параметр style . Так что если вы измените первый 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)

I действительно хотелось бы, чтобы был способ указать литералы даты и времени в T-SQL.

EDIT

Как указал Арво в комментариях ( спасибо , Арво), можно использовать литеральный формат метки времени ODBC (даже при использовании OLE DB), поэтому вторую функцию выше можно было бы записать как

IF @DateTimeIn < {d '1900-01-01'}
    RETURN {d '1900-01-01'}
...etc.

и преобразование в datetime выполняется во время компиляции, а не во время выполнения. Обратите внимание, что формат даты должен быть очень конкретным (см. Ссылка Arvo на тип данных datetime ):

д гггг-мм-дд
т чч: мм: сс [.fff]
тс гггг-мм-дд чч: мм: сс [.fff]

4 голосов
/ 21 ноября 2008

Из статей, на которые вы ссылались:

Чтобы быть детерминированным, параметр стиля должен быть константой. Кроме того, стили, меньшие или равные 100, являются недетерминированными, за исключением стилей 20 и 21. Стили больше 100 являются детерминированными, за исключением стилей 106, 107, 109 и 113.

Вам нужно использовать параметр стиля в ваших преобразованиях в datetime.

Например:

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

За исключением того, что не использовать 121 ...

...