2016-07-14 5 views
1

프로젝트에 내가 일하고 있어요 효율적 요청 페이지를 매기는 데 사용되는 패턴 즉오라클 ROW_NUMBER() OVER (오 데르 BY ...) 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 

처럼 액세스되는 오라클 (11) 데이터베이스가 있습니다. 이것은 생산 과정에서 완벽하게 작동합니다.

이제 단위 테스트를 위해 HSQLDB를 소개하겠습니다. (다른 메모리 DBMS뿐만 아니라 할 것입니다 아래를 참조하십시오.). 그러나, 나는 오라클 구문 호환성 모드 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에서도 사용할 수 있습니까?
아니면 어떤 점을 놓쳤습니까?


업데이트 : 응용 프로그램은 불행하게도, 오라클 11에서 실행되고 있습니다.

+1

HSQLDB는 창 기능을 지원하지 않습니다 (현재 임베디드 DBMS는 지원하지 않습니다). 오라클 12를 사용하는 경우'offset x 첫 번째 행 만 가져 오기 '를 사용할 수 있습니다. 그것도 HSQLDB에서 작동합니다. 그러나 당신은 다른 많은 작은 차이점을 우연히 발견하게 될 것입니다. (내 눈에는) 테스트가 꽤 무의미합니다. –

+1

@a_horse_with_no_name 올바른 답을 얻었습니다. 답변으로 게시하십시오. – fredt

답변

3

오라클 (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 

: 당신이 할 행의 수를 지정해야


(나는 내 ​​예제에서 #{num_rows}#{last_row}을 변경 그 이유는), 페이지 당 마지막 행이 아닌 절대 행 번호를 가져 그러나 일반적으로 나는 그것이 DIF를 사용하는 것은 좋은 생각 인 것 같아요 그럼에도 불구하고 프로덕션에서 테스트를위한 완벽한 DBMS가 있습니다. 내 의견으로는 테스트를 쓸모 없게 만드는 미묘한 차이가 있습니다.