HSQLDB中的Oracles ROW_NUMBER()OVER(ODER BY ...)

时间:2016-07-14 08:19:32

标签: oracle hsqldb window-functions in-memory-database

我正在开发的项目有一个Oracle 11数据库,可以像

一样访问
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

这是用于有效地分页请求的模式。这在生产中非常精细。

现在我想介绍HSQLDB进行单元测试。 (其他内存中的DBMS也可以。见下文。)但是,即使我使用Oracle语法兼容模式SET DATABASE SQL SYNTAX ORA TRUE;创建模式,我也会收到以下错误消息:

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 ////

这是HSQLDB的一些问题吗?可能没有实施。
我有什么可以做的吗? HSQLDB的任何替代方案都有更好的Oracle SQL支持吗? 是否存在另一种分页模式,这在Oracle中是有效的 - 不仅LOG_TABLE随着时间的推移而变得很大 - 并且在HSQLDB中可用? 或者我错过了一些观点?

更新:不幸的是,应用程序正在Oracle 11上运行。

1 个答案:

答案 0 :(得分:4)

如果您使用的是Oracle 12,则可以使用与HSQLDB一起使用的ANSI SQL fetch first x rows only

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 

现有代码存在差异:您需要指定每页要提取的行数,而不是最后一行的绝对行数(这就是为什么我将#{last_row}更改为在我的例子中#{num_rows}

但总的来说,我认为在生产中使用不同的DBMS进行测试是个坏主意。在我看来,有太多微妙的差异使得测试徒劳无功

相关问题