{"record":{"id":"fa44c59ff131c77d","repo":"pagehelper-org/Mybatis-PageHelper","slug":"the-pagination-statement-already-contains-the-top","errorCode":null,"errorMessage":"The pagination statement already contains the top, and can no longer be used to query the pagination plugin!","messagePattern":"The pagination statement already contains the top, and can no longer be used to query the pagination plugin!","errorType":"exception","errorClass":"PageException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/github/pagehelper/parser/defaults/DefaultSqlServerSqlParser.java","lineNumber":137,"sourceCode":"        if (limit != null) {\n            pageSql = pageSql.replace(PAGE_SIZE, String.valueOf(limit));\n        }\n        return pageSql;\n    }\n\n    /**\n     * 获取一个外层包装的TOP查询\n     *\n     * @param select\n     * @return\n     */\n    protected Select getPageSelect(Select select) {\n        if (select instanceof SetOperationList) {\n            select = wrapSetOperationList((SetOperationList) select);\n        }\n        //这里的selectBody一定是PlainSelect\n        if (((PlainSelect) select).getTop() != null) {\n            throw new PageException(\"The pagination statement already contains the top, and can no longer be used to query the pagination plugin!\");\n        }\n        //获取查询列\n        List<SelectItem<?>> selectItems = getSelectItems((PlainSelect) select);\n        //对一层的SQL增加ROW_NUMBER()\n        List<SelectItem<?>> autoItems = new ArrayList<>();\n        SelectItem<?> orderByColumn = addRowNumber((PlainSelect) select, autoItems);\n        //加入自动生成列\n        ((PlainSelect) select).addSelectItems(autoItems.toArray(new SelectItem[0]));\n        //处理子语句中的order by\n        processSelectBody(select, 0);\n\n        //中层子查询\n        PlainSelect innerSelectBody = new PlainSelect();\n        //PAGE_ROW_NUMBER\n        innerSelectBody.addSelectItems(orderByColumn);\n        innerSelectBody.addSelectItems(selectItems.toArray(new SelectItem[0]));\n        //将原始查询作为内层子查询\n        ParenthesedSelect fromInnerItem = new ParenthesedSelect();","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/pagehelper-org/Mybatis-PageHelper/blob/c692616c5bc95b41aa779b502f991825c8e5acbc/src/main/java/com/github/pagehelper/parser/defaults/DefaultSqlServerSqlParser.java#L119-L155","documentation":"Thrown when the SQL Server pagination converter finds the query already has a TOP clause. Applying the ROW_NUMBER pagination rewrite on top of an existing TOP would produce nested/incorrect pagination, so PageHelper refuses to paginate such SQL.","triggerScenarios":"Paginating SQL that already contains SELECT TOP n ... (or TOP n PERCENT) with the sqlserver dialect, e.g. helperDialect=sqlserver while the mapper SQL itself uses TOP.","commonSituations":"Legacy SQL fragments that hardcode TOP for limited fetches combined with PageHelper.startPage; developers copying TOP-based SQL from old code then adding the plugin; count/pagination applied on an already-limited inner query.","solutions":["Remove the TOP clause from the original SQL and let PageHelper control the limit","Use PageHelper.startPage(offset/limit) instead of TOP for row limiting","Switch to a dialect/rewriting mode compatible with TOP if TOP must remain","Refactor the mapper to a plain SELECT and express limits via page parameters"],"exampleFix":"// before\nString sql = \"SELECT TOP 10 * FROM orders\";\n// after\nString sql = \"SELECT * FROM orders\";\nPageHelper.startPage(1, 10);","handlingStrategy":"validation","validationCode":"java.util.regex.Pattern TOP = java.util.regex.Pattern.compile(\"(?i)SELECT\\\\s+TOP\\\\s+\\\\d\");\nif (TOP.matcher(sql).find()) {\n    throw new IllegalArgumentException(\"Remove TOP clause before PageHelper pagination\");\n}","typeGuard":null,"tryCatchPattern":"try { PageHelper.startPage(1, 10); mapper.list(); } catch (PageException e) {\n    if (e.getMessage().contains(\"top\")) { /* strip TOP from SQL and retry */ }\n}","preventionTips":["Do not hardcode SELECT TOP in mapper SQL used with the sqlserver dialect","Express row limits exclusively via PageHelper page parameters","Search codebase for 'TOP ' before enabling SQL Server pagination","Use OFFSET/FETCH (sqlserver2012) patterns instead of TOP when manual paging is needed"],"tags":["java","pagehelper","sqlserver","conflicting-options"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"c692616c5bc95b41aa779b502f991825c8e5acbc","analyzedAt":"2026-09-08T03:50:49.192Z","contentChangedAt":"2026-09-08T03:50:49.192Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}