5

En la tradición de this question ya la luz de the documentation, ¿cómo hacer esta función determinista:¿Cómo hacer conversiones de varchar a datetime deterministic?

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 

O ésta (debido a los literales de cadena/hora - y sí, también he intentado '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 

Respuesta

6

BOL dice que CONVERT es determinista con datetimes si no se especifica el parámetro estilo. Por lo que si se cambia la primera UDF para:

RETURN CONVERT(datetime, CONVERT(varchar, @DATA_DT_ID), 112) 

Entonces debe ser determinista, si entiendo la documentación correctamente.

Presumiblemente, el mismo truco se podría utilizar en su segunda UDF:

IF @DateTimeIn < CONVERT(datetime, '1/1/1900', 101) 
    RETURN CONVERT(datetime, '1/1/1900', 101) 

I realmente Me gustaría que hubiese una forma de especificar los literales de fecha y hora en T-SQL.

EDITAR:

Como ha señalado Arvo en los comentarios (gracias, Arvo), el formato literal ODBC marca de tiempo se puede utilizar (incluso cuando se utilizan OLE DB) por lo que la segunda función anterior podría mejor escrito como:

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

y la conversión a fecha y hora se realiza en tiempo de compilación en lugar de tiempo de ejecución. Tenga en cuenta que el formato de la fecha tiene que ser muy específico (ver Arvo's link to the datetime data type):

  d         aaaa-mm-dd
  t         hh: mm: ss [.fff ]
ts         aaaa-mm-dd hh: mm: ss [.fff]

+0

Solo he usado el estilo al convertir TO varchar: la documentación es un poco ambigua, pero lo probé y funciona claramente. –

+0

@P Daddy, Amen en los literales de fecha y hora. –

+2

Acerca de los literales de fecha y hora: ¿no puede usar el formato de indicación de fecha y hora de ODBC como {d '1990-10-02'}? Desde http://msdn.microsoft.com/en-us/library/ms187819.aspx: Las aplicaciones que usan ADO, OLE DB y API basadas en ODBC pueden usar este formato de marca de tiempo ODBC para representar fechas y horas. – Arvo

2

De los artículos que vinculado:

Para ser determinista, el parámetro de estilo debe ser una constante. Además, los estilos de menores o iguales a 100 son no determinista, a excepción de estilos 20 y 21. Estilos de más de 100 son deterministas, a excepción de estilos 106, 107, 109 y 113.

Es necesario utilizar un parámetro de estilo en tus conversiones a datetime

Por ejemplo:

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

Excepto no utilizan 121 ...

+0

¿No hay fechas literales como cadenas en UDF sin CONVERTIR? –

+0

Si las cadenas se convierten a fechas implícitamente, esas conversiones carecen de estilos "constantes" y harán que la función sea no determinista. –

Cuestiones relacionadas