From d5abb8deeb78e16589737bd4ae2757e678af30f8 Mon Sep 17 00:00:00 2001 From: nieqiurong Date: Sat, 27 Apr 2024 09:00:20 +0800 Subject: [PATCH] =?UTF-8?q?SQLServer2005=E5=88=86=E9=A1=B5=E4=BC=98?= =?UTF-8?q?=E5=8C=96.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dialects/SQLServer2005Dialect.java | 18 +++++------ .../pagination/SQLServer2005DialectTest.java | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/dialects/SQLServer2005Dialect.java b/mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/dialects/SQLServer2005Dialect.java index 5c07c7d66..4e4458107 100644 --- a/mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/dialects/SQLServer2005Dialect.java +++ b/mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/dialects/SQLServer2005Dialect.java @@ -30,7 +30,9 @@ */ public class SQLServer2005Dialect implements IDialect { - private static final Pattern pattern = Pattern.compile("\\((.)*order by(.)*\\)"); + private static final Pattern ORDER_BY_PATTERN = Pattern.compile("\\((.)*order by(.)*\\)"); + + private static final Pattern SELECT_PATTERN = Pattern.compile("(?i)select\\s+(distinct\\s+)?"); public String getOrderByPart(String sql) { String order_by = "order by"; @@ -38,7 +40,7 @@ public String getOrderByPart(String sql) { if (lastIndex == -1) { return StringPool.EMPTY; } - Matcher matcher = pattern.matcher(sql); + Matcher matcher = ORDER_BY_PATTERN.matcher(sql); if (!matcher.find()) { return sql.substring(lastIndex); } @@ -51,20 +53,16 @@ public DialectModel buildPaginationSql(String originalSql, long offset, long lim StringBuilder pagingBuilder = new StringBuilder(); String orderby = getOrderByPart(originalSql); String distinctStr = StringPool.EMPTY; - - String loweredString = originalSql.toLowerCase(); String sqlPartString = originalSql; - String trimStr = loweredString.trim(); - if (trimStr.startsWith("select")) { - int index = loweredString.indexOf("select") + 6; - if (trimStr.startsWith("select distinct")) { + Matcher matcher = SELECT_PATTERN.matcher(originalSql); + if (matcher.find()) { + int index = matcher.end() - 1; + if (matcher.group().toLowerCase().contains("distinct")) { distinctStr = "DISTINCT "; - index = loweredString.indexOf("select distinct") + 15; } sqlPartString = sqlPartString.substring(index); } pagingBuilder.append(sqlPartString); - // if no ORDER BY is specified use fake ORDER BY field to avoid errors if (StringUtils.isBlank(orderby)) { orderby = "ORDER BY CURRENT_TIMESTAMP"; diff --git a/mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/test/plugins/pagination/SQLServer2005DialectTest.java b/mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/test/plugins/pagination/SQLServer2005DialectTest.java index cda88e889..332cd6c14 100644 --- a/mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/test/plugins/pagination/SQLServer2005DialectTest.java +++ b/mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/test/plugins/pagination/SQLServer2005DialectTest.java @@ -22,6 +22,37 @@ void test() { "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" select *,(select 1) from test", 1, 10).getDialectSql(), "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("select distinct *,(select 1) from test", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT DISTINCT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" select distinct *,(select 1) from test", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT DISTINCT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("select *,(select 1) from test", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" select *,(select 1) from test", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("select * from test", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, * from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" select * from test", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, * from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("SELECT DISTINCT *,(SELECT 1) FROM TEST", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT DISTINCT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(SELECT 1) FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" SELECT DISTINCT *,(SELECT 1) FROM TEST", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT DISTINCT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(SELECT 1) FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("SELECT *,(SELECT 1) FROM TEST", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(SELECT 1) FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" SELECT *,(SELECT 1) FROM TEST", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, *,(SELECT 1) FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("SELECT * FROM TEST", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, * FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" SELECT * FROM TEST", 1, 10).getDialectSql(), + "WITH selectTemp AS (SELECT TOP 100 PERCENT ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, * FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__"); + } }