重写查询以进行分页

时间:2017-03-03 05:10:04

标签: java sql db2

我有一个程序,用户提供可以在数据库上执行的sql查询(运行的数据库的详细信息也由用户提供)。此查询在数据库上执行,结果将在稍后处理。

新功能要求查询以分页方式执行,即如果用户的查询正常返回20条记录,并且用户提供的页面大小为5,则查询应执行4次,每次检索5条记录。

我可以为没有CTE的选择查询执行此操作,但我不确定如何处理包含CTE的常规查询。

我修改了CTE的查询,如下所示:

public static String rewrite(String sql) {
    return "select * from ("
            + "select (row_number() over ()) as generated_row_number, t.* "
            + "from ("
            + sql
            + ") as t"
            + ") "
            + "where generated_row_number < ?"
            + " and generated_row_number >= ?"; 
}

以后将起始索引和页面大小添加为参数。

如何处理包含CTE的查询的类似功能?

可以假设数据库是DB2,尽管通用解决方案是首选。

连接到数据库的用户也没有创建视图的权限。

2 个答案:

答案 0 :(得分:0)

在SQL中查询的一种方便方法是使用offset-fetch。我常常将它用于分页。

Select StockCode,Description,Quantity from Inventory order by StockCode offset 0 ROWS fetch NEXT 5 ROWS ONLY

所以在代码中它会像

public static string(int Page, int PerPage)
{
    return "Select StockCode,Description,Quantity from Inventory order by StockCode offset " + ((Page - 1) * PerPage).ToString() + " ROWS fetch NEXT " + PerPage.ToString() + " ROWS ONLY"
}

如果您需要更通用的解决方案,可以尝试嵌套选择:

public static String rewrite(String sql, int Page, int PerPage)
{
    return "Select * from (" + sql + ") order by 1 offset " + ((Page - 1) * PerPage).ToString() + " ROWS fetch NEXT " + PerPage.ToString() + " ROWS ONLY"
}

答案 1 :(得分:0)

试试这个:

public static String rewrite(String sql) 
{
    return   "with tmptable as (" + sql + ")"
            + " select * from ("
            + " select row_number() over () as generated_row_number, t.* "
            + " from tmptable t
            + ") tmp"
            + " where tmp.generated_row_number < ?"
            + " and tmp.generated_row_number >= ?"; 
}