2016-07-14 31 views
1

Das Projekt arbeite ich an hat eine Oracle-11-Datenbank, die wieOracles ROW_NUMBER() OVER (ODER NACH ...) in HSQLDB

SELECT * 
    FROM (
    SELECT row_number() over (ORDER BY acme_dept.LOG_TABLE.LOG_TIME ASC) rn, 
     acme_dept.LOG_TABLE.LOG_TIME, 
     acme_dept.LOG_TABLE.LOG_LEVEL, 
     acme_dept.LOG_TABLE.MESSAGE, 
     acme_dept.LOG_TABLE.CATEGORY, 
    FROM acme_dept.LOG_TABLE 
    ) 
    WHERE rn BETWEEN #{first_row} AND #{last_row} 
    ORDER BY rn 

zugegriffen wird, dass das Muster effizient Paginieren Anfragen verwendet wird. Das funktioniert in der Produktion einwandfrei.

Jetzt möchte ich HSQLDB für Komponententests einführen. (Weiterer In-Memory-DBMS als auch tun würde, siehe unten.). Aber auch, wenn ich das Schema mit Oracle-Syntax-Kompatibilitätsmodus erstellen SET DATABASE SQL SYNTAX ORA TRUE;, erhalte ich die folgende Fehlermeldung:

org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database. Cause: java.sql.SQLSyntaxErrorException: unexpected token: ORDER required:) : line: 4 in statement [SELECT * 
    FROM (
    SELECT row_number() over (
     ORDER BY acme_dept.LOG_TABLE.LOG_TIME ASC) rn, 
     acme_dept.LOG_TABLE.LOG_TIME, 
     acme_dept.LOG_TABLE.LOG_LEVEL, 
     acme_dept.LOG_TABLE.MESSAGE, 
     acme_dept.LOG_TABLE.CATEGORY, 
    FROM acme_dept.LOG_TABLE 
    ) 
    WHERE rn BETWEEN #{first_row} AND #{last_row} 
    ORDER BY rn 

//// stacktrace ommited //// 

Ist das eine Ausgabe mit HSQLDB ? Nur nicht vielleicht implementiert.
Kann ich irgendetwas dagegen tun?
Haben Alternativen zu HSQLDB bessere Oracle SQL-Unterstützung?
Gibt es ein weiteres Paginierungsmuster, das in Oracle effizient ist - nicht nur das LOG_TABLE wurde im Laufe der Zeit groß - und in HSQLDB verfügbar?
Oder habe ich einen Punkt verpasst?


Update: Anwendung läuft auf 11 Oracle, leider.

+1

HSQLDB unterstützt keine Fensterfunktionen (kein eingebettetes DBMS tut im Moment). Wenn Sie Oracle 12 verwenden, können Sie 'offset x holen nur die ersten y Zeilen 'verwenden. Das funktioniert auch in HSQLDB. Aber Sie werden über viele andere kleine Unterschiede stolpern, wenn Sie das tun, was (zumindest in meinen Augen) die Tests ziemlich bedeutungslos macht. –

+1

@a_horse_with_no_name Sie haben die richtige Antwort. Bitte post als Antwort. – fredt

Antwort

3

Wenn Sie 12 Oracle verwenden, können Sie die ANSI SQL fetch first x rows only verwenden, die auch mit HSQLDB funktioniert:

SELECT acme_dept.LOG_TABLE.LOG_TIME, 
     acme_dept.LOG_TABLE.LOG_LEVEL, 
     acme_dept.LOG_TABLE.MESSAGE, 
     acme_dept.LOG_TABLE.CATEGORY, 
FROM acme_dept.LOG_TABLE 
ORDER BY acme_dept.LOG_TABLE.LOG_TIME ASC 
OFFSET #{first_row} 
FETCH FIRST #{num_rows} ROWS ONLY 

Es gibt einen Unterschied zu Ihrem vorhandenen Code: Sie können die Anzahl der Zeilen angeben müssen sein pro Seite holen, nicht die absolute Zeilennummer für die letzte Zeile (das ist, warum ich #{last_row} zu #{num_rows} in meinem Beispiel geändert)


Aber im allgemeinen denke ich, es ist eine schlechte Idee ist, eine dif zu verwenden DBMS zu testen, dann in der Produktion.Es gibt zu viele feine Unterschiede, die die Tests sinnlos machen