2017-03-03 48 views
2

我有一個程序,其中用戶提供了一個可以在數據庫上執行的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,儘管通用解決方案將是首選。

連接到數據庫的用戶也沒有創建視圖的權限。

+0

如何使用偏移量? 「爲了1偏移10((頁碼 - 1)* PAGESIZE)行獲取下一個5(頁面大小)行僅對」 – Appleman

回答

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" 
} 
+0

我碰到下面的錯誤,使用這樣的:'請從測試 *抵消未來20行取20行only' '意外的標記「從測試」之後發現「SELECT *」。預期標記可能包括: 「」 .. SQLCODE = -104,SQLSTATE = 42601,DRIVER = 4.13.127 ' – BX21

+0

你需要有 – Appleman

+0

「按訂單」 還不行:'1 SELECT * FROM測試 秩序 偏移20行 僅 異常標記獲取下一個20行的「偏移20行 獲取下一個20行僅」之後發現「米測試 爲了通過1 」。預期標記可能包括: 「」 .. SQLCODE = -104,SQLSTATE = 42601,DRIVER = 4.13.127' – BX21

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 >= ?"; 
} 
+0

這不工作,如果原來的查詢還包含WITH子句,這是我遇到的麻煩。它也不適用於一些簡單的選擇,失敗時出現錯誤-153 – BX21