簡體   English   中英

使用PHP模擬進行中的LIMIT(FETCH),OFFSET的有效方法

[英]Efficient way of emulating LIMIT (FETCH), OFFSET in Progress OpenEdge 10.1B SQL using PHP

我希望能夠在OpenEdge 10.1b中使用等效於MySQL的LIMIT,OFFSET。

盡管FETCH / OFFSET命令從Open Edge 11開始可用,但是不幸的是,版本10.1B沒有它們,因此很難生成分頁記錄集(例如,記錄1-10、11-20、21-30等)。

10.1b也不支持ROW_NUMBER。 似乎它與SQL Server 2000中的功能幾乎相同。

如果始終按主鍵id(pkid)的順序進行搜索,則可以使用“ SELECT TOP 10 * FROM table ORDER BY pkid ASC”,然后標識最后一個pkid,然后使用“ SELECT TOP 10 *從表WHERE pkid> last_pkid ORDER BY pkid ASC“; 但是,這僅在按pkid排序時有效。

我對此的解決方案是編寫一個PHP函數,在該函數中可以傳遞限制和偏移量,然后僅返回行號在那些定義的值之間的結果。 我使用TOP返回的值不超過限制和偏移量的總和。

function limit_query($sql, $limit=NULL, $offset=0)
    {
        $out      = array();
        if ($limit!=NULL) {
            $sql=str_replace_first("SELECT", "SELECT TOP ".($limit+$offset), $sql);
        }
        $query = $db->query($sql); //$db is my DB wrapper class
        $i=0;
        while ($row = $this->fetch($query)) {
            if ($i>=$offset) { //only add to return array if greater than offset
                $out[] = $row;
            }
            $i++;
        }
        $db->free_result($query);
        return $out;
    }

這在小型記錄集或結果的前幾頁上效果很好,但是如果總結果成千上萬,那么如果您想在第20、100或300頁上查看結果,那將非常緩慢且效率低下(第一頁正在查詢僅前10個結果,第2頁為前20個,但第100頁將查詢前1000個)。

盡管在大多數情況下,用戶可能不會冒險瀏覽第2頁或第3頁,所以缺乏效率可能不是主要問題,但我確實想知道是否有一種更有效的方法來仿真此功能。

遺憾的是,由於數據庫是由第三方軟件提供的,因此不能選擇升級到Progress的較新版本或高級數據庫(如MySQL)。

誰能建議其他更有效的方法?

我不確定我是否完全理解這個問題,因此嘗試為您提供一個答案:一次命中數據庫可能無法完成您想要的操作。 僅通過對記錄進行排序/添加功能,您可能無法實現您想要獲得的分頁功能。 據我所知,Progress不會對行進行編號,除非您按照您所說的那樣按新月形pkid進行排序。 我的建議是在后端運行一個過程,以創建與頁面相同的批處理大小的查詢(在您的情況下為10),並使用循環獲取下一個批處理,直到獲得所需的批處理為止。 查看批處理數據集或使用MAX-ROWS使用開放式查詢。 希望它會有所幫助,或者至少給您一個想法。 我實際上喜歡您的PHP實現,這似乎是一個不錯的解決方法,很難保留。

您應該能夠安裝Progress的升級版本,轉換數據庫並針對新版本重新編譯代碼。 通常,您通過供應商提供的支持將為您提供最新版本的Progress(Openedge),而不是一個大問題。 從版本10到版本11應該不會引起任何編譯問題,並為您提供較新版本的所有SQL好處。

老實說,您對MySql優越的評價有點令人困惑,但這是另一天的討論。 ; d

最好的祝福!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM