sqlserver 2012 offset 페이지
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package com.github.drinkjava2.jdialects.hibernatesrc.pagination;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* LIMIT clause handler compatible with SQL Server 2012 and later.
*
* @author Chris Cranford
*/
public class SQLServer2012LimitHandler extends SQLServer2005LimitHandler {
// determines whether the limit handler used offset/fetch or 2005 behavior.
private boolean usedOffsetFetch;
public SQLServer2012LimitHandler() {
// empty
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public boolean supportsVariableLimit() {
return true;
}
@Override
public String processSql(String sql, RowSelection selection) {
// SQLServer mandates the following rules to use OFFSET/LIMIT
// * An 'ORDER BY' is required
// * The 'OFFSET ...' clause is mandatory, cannot use 'FETCH ...' by itself.
// * The 'TOP' clause isn't permitted with LIMIT/OFFSET.
if (hasOrderBy(sql)) {
if (!LimitHelper.useLimit(this, selection)) {
return sql;
}
return applyOffsetFetch(selection, sql, getInsertPosition(sql));
}
return super.processSql(sql, selection);
}
@Override
public boolean useMaxForLimit() {
// when using the offset fetch clause, the max value is passed as-is.
// SQLServer2005LimitHandler uses start + max values.
return usedOffsetFetch ? false : super.useMaxForLimit();
}
@Override
public int convertToFirstRowValue(int zeroBasedFirstResult) {
// When using the offset/fetch clause, the first row is passed as-is
// SQLServer2005LimitHandler uses zeroBasedFirstResult + 1
if (usedOffsetFetch) {
return zeroBasedFirstResult;
}
return super.convertToFirstRowValue(zeroBasedFirstResult);
}
@Override
public int bindLimitParametersAtEndOfQuery(RowSelection selection, PreparedStatement statement, int index)
throws SQLException {
if (usedOffsetFetch && !LimitHelper.hasFirstRow(selection)) {
// apply just the max value when offset fetch applied
statement.setInt(index, getMaxOrLimit(selection));
return 1;
}
return super.bindLimitParametersAtEndOfQuery(selection, statement, index);
}
private String getOffsetFetch(RowSelection selection) {
if (!LimitHelper.hasFirstRow(selection)) {
return " offset 0 rows fetch next ? rows only";
}
return " offset ? rows fetch next ? rows only";
}
private int getInsertPosition(String sql) {
int position = sql.length() - 1;
for (; position > 0; --position) {
char ch = sql.charAt(position);
if (ch != ';' && ch != ' ' && ch != '\r' && ch != '
') {
break;
}
}
return position + 1;
}
private String applyOffsetFetch(RowSelection selection, String sql, int position) {
usedOffsetFetch = true;
StringBuilder sb = new StringBuilder();
sb.append(sql.substring(0, position));
sb.append(getOffsetFetch(selection));
if (position > sql.length()) {
sb.append(sql.substring(position - 1));
}
return sb.toString();
}
private boolean hasOrderBy(String sql) {
int depth = 0;
for (int i = 0; i < sql.length(); ++i) {
char ch = sql.charAt(i);
if (ch == '(') {
depth++;
} else if (ch == ')') {
depth--;
}
if (depth == 0 && sql.substring(i).toLowerCase().startsWith("order by ")) {
return true;
}
}
return false;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.