什么都沒(méi)有的路邊攤

          無(wú)證小販

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            7 Posts :: 0 Stories :: 4 Comments :: 0 Trackbacks

          分頁(yè)(Paging) / SQL Server / Oracle
          雖然 DataGrid 控件自己帶了一個(gè)分頁(yè)處理機(jī)制,但它是將符合查詢條件的所有記錄讀入內(nèi)存,然后進(jìn)行分頁(yè)顯示的。隨著符合條件的記錄數(shù)目增多,就會(huì)出現(xiàn)運(yùn)行效率問(wèn)題,或者至少是資源的利用率下降。

          下面的代碼示例都以下面的表結(jié)構(gòu)為準(zhǔn):

              Articles 表     SQL Server 類型      Oracle 類型
          PK    Id              int (自增)            number(9) (插入時(shí)在當(dāng)前最大值上加1)
               Author          nvarchar(10)         nvarchar2(10)
               Title           nvarchar(50)         nvarchar2(50)
               PubTime         datetime date


          SQL Server / Access 等微軟產(chǎn)品中,我們通常的自定義分頁(yè)有兩種思路:

          一種是以 ASP.NET Forum 為代表的、“臨時(shí)表”方法:即在存儲(chǔ)過(guò)程中建立一個(gè)臨時(shí)表,該臨時(shí)表包含一個(gè)序號(hào)字段(1,2,3,....)以及表的主鍵(其他能夠唯一確定一行記錄的字段也是可以的)字段。存儲(chǔ)過(guò)程可能如下:(編號(hào) SS1)

          CREATE Procedure GetAllArticles_Paged
          (
               @PageIndex int,
               @PageSize int,
               @TotalRecords out int,
               @TotalPages out int
          )
          AS

          DECLARE @PageLowerBound int
          DECLARE @PageUpperBound int

          -- Set the page bounds
          SET @PageLowerBound = @PageSize * @PageIndex
          SET @PageUpperBound = @PageLowerBound + @PageSize + 1

          -- Create a temp table to store the select results
          CREATE TABLE #tmp
          (
               RecNo int IDENTITY (1, 1) NOT NULL,
               ArticleID int
          )

          INSERT INTO #tmp
               SELECT [ID]
               FROM Articles
               ORDER BY PubTime DESC

          SELECT A.*
          FROM Articles A (nolock), #tmp T
          WHERE A.ID = T.ArticleID AND
               T.RecNo > @PageLowerBound AND
               T.RecNo < @PageUpperBound
          ORDER BY T.RecNo

          GO
          另一種可能更適合程序中“拼湊” SQL 語(yǔ)句:用兩次 TOP 命令取得我們所要的分頁(yè)數(shù)據(jù),例如:(編號(hào) SS2)

          SELECT * FROM
               (
               SELECT TOP(PageSize) * FROM
               (
                    SELECT TOP (PageSize * PageIndex) *
                    FROM Articles
                    ORDER BY PubTime DESC
               )
               ORDER BY PubTime ASC
          )
          ORDER BY PubTime DESC
          這個(gè)的想法就是“掐頭去尾”,還有不少分頁(yè)的方法,這里就不一一列出了。

          對(duì)于 Oracle 數(shù)據(jù)庫(kù),有幾處不同嚴(yán)重妨礙了上面幾個(gè)方法的實(shí)施,比如,Oracle 不支持 TOP 關(guān)鍵字:不過(guò)這個(gè)好像并不十分嚴(yán)重,因?yàn)樗峁┝?rownum 這個(gè)隱式游標(biāo),可以實(shí)現(xiàn)與 TOP 類似的功能,如:

          SELECT TOP 10 ... FROM WHERE ...
          要寫成

          SELECT ... FROM ... WHERE ... AND rownum <= 10
          rownum 是記錄序號(hào)(1,2,3...),但有一個(gè)比較麻煩的事情是:如果 SQL 語(yǔ)句中有 ORDER BY ... 排序的時(shí)候,rownum 居然是先“標(biāo)號(hào)”后排序!這樣,這個(gè)序號(hào)如果不加處理是不合乎使用需求的。

          至于臨時(shí)表,Oracle 的臨時(shí)表和 SQL Server 的有很大不同,我還沒(méi)搞懂這個(gè)東西,就不妄加揣測(cè)了。

          國(guó)內(nèi)網(wǎng)站中介紹 Oracle 分頁(yè)的資料很少,我找到了一個(gè)國(guó)外站點(diǎn)(www.faqts.com)的一篇 FAQ,根據(jù)這篇文章的介紹,可以如下分頁(yè):(編號(hào) Ora1)

          SELECT * FROM
               (
               SELECT A.*, rownum r
               FROM
                    (
                    SELECT *
                    FROM Articles
                    ORDER BY PubTime DESC
                    ) A
               WHERE rownum <= PageUpperBound
               ) B
          WHERE r > PageLowerBound;

          posted on 2007-04-16 23:46 shadeclipse 閱讀(219) 評(píng)論(0)  編輯  收藏 所屬分類: 技術(shù)堆累
          主站蜘蛛池模板: 托里县| 上高县| 鄯善县| 莱芜市| 定南县| 德钦县| 枣阳市| 西乌| 长兴县| 青铜峡市| 宣武区| 鲁山县| 博乐市| 焉耆| 永兴县| 富蕴县| 秦安县| 景宁| 合作市| 乳源| 沙雅县| 简阳市| 贺兰县| 左贡县| 南丰县| 中阳县| 墨竹工卡县| 根河市| 绵竹市| 莱阳市| 卓资县| 宜宾市| 承德市| 定结县| 高青县| 花莲市| 通辽市| 丹阳市| 耒阳市| 江北区| 昭苏县|