2009-03-12 3 views
16

Ich schaue, wie man Datum/Zeit Mathe innerhalb einer HQL Abfrage durchführt. Genauer gesagt, wie addiere oder subtrahiere ich (x) die Zeitmenge vom Ergebnis der Funktion current_timestamp()? Oder muss ich dafür in SQL gehen und hoffen, dass, was auch immer Datenbank ausgeführt wird, es unterstützt?Durchführen von Datums-/Zeitmathematik in HQL?

HQL Abfrage Beispiel:

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

kann ich definieren: timeToSubtract Parameter eine bestimmte Einheit zu sein, obwohl etwas größer als Stunden unerwünscht wäre, und Sekunden wären sehr wünschenswert.

Erläuterung: Ich weiß, dass dies leicht außerhalb der Abfrage durchgeführt werden kann. Aber aus philosophischen Gründen ist es beispielsweise wichtig, die Zeit des Datenbankservers zu verwenden und nicht die Zeit des Abfragesystems. Praktisches Beispiel: Ich frage einen automatischen Zeitstempel für alle Einträge innerhalb der letzten (x) Zeit. Da der Zeitstempel vom Datenbanksystem erstellt wird, ist es wichtig, auch die aktuelle Zeit der Datenbank zu verwenden.

+0

Ich bin auch auf der Suche nach der gleichen Sache, außer dass die TimeToAdd ist kein Parameter, sondern eine Spalte aus der gleichen Zeile, so dass es keinen Sinn macht, eine zweite Abfrage für die gleiche Zeile und Tabelle. – James

Antwort

3

Wenn Sie den Datenbankserver Zeit benötigen, könnten Sie zunächst eine einfache HQL Abfrage tun, um den Zeitstempel zu erhalten und dann die maxTimestamp in Java berechnen und den abgerufenen geben timestamp und der berechnete maxTimeStamp für eine Abfrage wie die von ccclark.

+0

Ich denke, das ist die am meisten verallgemeinerbare und einfach zu implementierende Lösung. Vielen Dank. – jdmichal

10

Warum müssen Sie es in der Abfrage tun? Warum behandeln Sie es nicht einfach im Java-Code?

zum Beispiel:

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

Und dann nur die Parameter einstellen.

+0

Gute Antwort. Ich habe die Frage mit meiner Antwort geklärt. – jdmichal

+2

Da der Java-Code möglicherweise nicht mit der gleichen Uhr läuft und in manchen Abfragen auch ein paar Sekunden Unterschied auftreten, kann dies zu Problemen führen. – Quartz

4

Sie können die Syntax dafür bestimmen, indem Sie SQL in Ihrer Datenbank verwenden und dann eine Funktion in einem benutzerdefinierten HibernateDialect definieren. Zum Beispiel benötigten wir eine Wochentagsfunktion, die kein Standard-SQL ist. Wir subclassed den Dialekt für jede Datenbank und fügte dann eine Zeile wie diese:

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

In Ihrem Fall eine Funktion date_diff genannt verwenden könnte, die wie folgt definiert werden könnte? -? in einigen Datenbanken oder etwas Anderes in anderen. Auf diese Weise müssen Sie in Ihrer Abfrage kein Raw SQL schreiben und wenn Sie jemals Datenbanken wechseln müssen, ordnen Sie die Funktion einfach in Ihrem Dialekt anders an.

1

Muss es HQL sein? Ich würde wahrscheinlich zu Hibernate Kriterien schalten und zu verwenden:

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

Was ist der Unterschied zwischen dem Einfügen dieser beiden Anweisungen in Kriterien in eine HQL-Abfrage? – jdmichal

+0

Diese Lösung funktioniert mit der CriteriaQuery-API, die nützlich ist, wenn dieser Ansatz bereits verfolgt wird. –