2009-03-12 15 views
16

Estoy buscando cómo realizar la matemática de fecha/hora dentro de una consulta HQL. Específicamente, ¿cómo agrego o resta (x) la cantidad de tiempo del resultado de la función current_timestamp()? ¿O tengo que recurrir a SQL para esto y espero que cualquier base de datos que se esté ejecutando lo soporte?Ejecutando fecha/hora Matemáticas en HQL?

HQL consulta de ejemplo:

FROM RandomThing 
WHERE randomTime IS NOT NULL AND 
     randomTime >= current_timestamp() AND 
     randomTime <= (current_timestamp() + :timeToAdd) 

I puede definir el: parámetro timeToSubtract ser cualquier unidad particular, aunque nada más grande que hora sería indeseable, y segundos sería más deseable.

ACLARACIÓN: Me doy cuenta de que esto se puede hacer fácilmente fuera de la consulta. Pero por razones filosóficas, digamos que es importante utilizar el tiempo del servidor de la base de datos, en lugar del tiempo del sistema de consultas. Ejemplo práctico: estoy consultando una marca de tiempo automática para todas las entradas realizadas dentro del último (x) período de tiempo. Dado que la marca de tiempo la realiza el sistema de base de datos, también es importante utilizar la hora actual de la base de datos.

+0

También estoy buscando lo mismo, excepto que timeToAdd no es un parámetro, sino una columna de la misma fila, por lo que no tiene sentido realizar una segunda consulta a la misma fila y tabla. – James

Respuesta

3

Si necesita más tiempo del servidor de base de datos, se puede hacer primero una consulta HQL sencilla de obtener la marca de tiempo y luego calcular el maxTimestamp en Java y pasar la descabellada la marca de tiempo y la maxTimeStamp calculada a una consulta como la de ccclark.

+0

Creo que esta es la solución más generalizable y fácil de implementar. Gracias. – jdmichal

10

¿Por qué necesita hacerlo en la consulta? ¿Por qué no solo manejarlo en el código java?

por ejemplo:

From RandomThing 
Where randomTime is not null and 
     randomTime >= :currentTimestamp and 
     randomTime <= :maxTimestamp 

Y entonces acaba de establecer los parámetros.

+0

Buena respuesta. Hice aclaraciones a la pregunta con mi respuesta. – jdmichal

+2

Debido a que es posible que el código de Java no se esté ejecutando en el mismo reloj, y en algunas consultas, incluso una diferencia de unos pocos segundos puede causar problemas. – Quartz

4

Puede determinar la sintaxis para hacerlo mediante SQL en su base de datos y luego definir una función dentro de un HibernateDialect personalizado. Por ejemplo, necesitamos una función de día de la semana que no sea SQL estándar. Nos subclases el dialecto de cada base de datos y luego agregamos una línea como esta:

registerFunction("weekday", 
    new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')")); 

En su caso, se puede utilizar una función llamada date_diff que podría definirse como? -? en algunas bases de datos o algo diferente en otros. De esta manera, no tiene que escribir SQL sin procesar en su consulta y si alguna vez necesita cambiar las bases de datos, solo asigna la función de forma diferente en su dialecto.

1

¿Tiene que ser HQL? Yo probablemente conmutar hasta un criterio de hibernación y uso:

Criteria.add(Restrictions.SQLRestriction("{alias} <= current_timestamp() ")) 
Criteria.add(Restrictions.SQLRestriction("{alias} >= (current_timestamp() + ?) ", 5) 
+1

¿Cuál es la diferencia entre poner esas dos afirmaciones en criterios en comparación con una consulta HQL? – jdmichal

+0

Esta solución funciona con la API de CriteriaQuery, que es útil si uno ya está siguiendo ese enfoque. –