001package com.avaje.ebean.config.dbplatform; 002 003/** 004 * Use top and row_number() function to limit sql results. 005 */ 006public class MsSqlServer2005SqlLimiter implements SqlLimiter { 007 008 final String rowNumberWindowAlias; 009 010 /** 011 * Specify the name of the rowNumberWindowAlias. 012 */ 013 public MsSqlServer2005SqlLimiter(String rowNumberWindowAlias) { 014 this.rowNumberWindowAlias = rowNumberWindowAlias; 015 } 016 017 public MsSqlServer2005SqlLimiter() { 018 this("as limitresult"); 019 } 020 021 public SqlLimitResponse limit(SqlLimitRequest request) { 022 023 StringBuilder sb = new StringBuilder(500); 024 025 int firstRow = request.getFirstRow(); 026 027 int lastRow = request.getMaxRows(); 028 if (lastRow > 0) { 029 lastRow = lastRow + firstRow; 030 } 031 032 if (firstRow < 1) { 033 // just use top n 034 sb.append(" select "); 035 if (request.isDistinct()) { 036 sb.append("distinct "); 037 } 038 sb.append(" top ").append(lastRow).append(" "); 039 sb.append(request.getDbSql()); 040 return new SqlLimitResponse(sb.toString(), false); 041 } 042 043 /* 044 * SELECT * FROM (SELECT TOP 20 ROW_NUMBER() OVER (ORDER BY ...) AS rn, ...) 045 * AS limitresult WHERE rn >= 11 AND rn <= 20 046 */ 047 048 sb.append("select * ").append(NEW_LINE).append("from ( "); 049 050 sb.append("select "); 051 if (request.isDistinct()) { 052 sb.append("distinct "); 053 } 054 sb.append("top ").append(lastRow); 055 sb.append(" row_number() over (order by "); 056 sb.append(request.getDbOrderBy()); 057 sb.append(") as rn, "); 058 sb.append(request.getDbSql()); 059 060 sb.append(NEW_LINE).append(") "); 061 sb.append(rowNumberWindowAlias); 062 sb.append(" where "); 063 if (firstRow > 0) { 064 sb.append(" rn > ").append(firstRow); 065 if (lastRow > 0) { 066 sb.append(" and "); 067 } 068 } 069 if (lastRow > 0) { 070 sb.append(" rn <= ").append(lastRow); 071 } 072 073 String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery()); 074 075 return new SqlLimitResponse(sql, true); 076 } 077 078}