<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Nothing is impossible for a willing heart

    I belive I can

     

    orcale數據分頁提取數

    orcale數據分頁提取數
    方法一:

    select top 10 b.* from (select top 20 主鍵字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主鍵字段 = a.主鍵字段 order by a.排序字段

    10 = 每頁記錄數

    20 = (當前頁 + 1) * 每頁記錄數

    以上語句即可以實現分頁,但是最后取出的結果排序是升序,如果需要結果集為降序(例如時間),則有兩種方法可以處理

    1.使用以下語句,但效率可能要降低一些

    select * from 表名 b, (select top 10 主鍵字段,排序字段 from (select top 20 主鍵字段,排序字段 from 表名 order by 排序字段 desc) a order by 排序字段 ) c where b.主鍵字段 = c.主鍵字段 order by c.排序字段 desc

    2.在ado里處理,將記錄集游標移到最后,然后前移

    ''以下為asp范例

    set rsTemp = Server.CreateObject("adodb.recordset")

    rsTemp.Open 語句,conn,1,1

    rsTemp.MoveLast

    for i = 1 to rsTemp.RecordCount

    ???? '取值....

    ??? rsTemp.MovePrevious

    next

    ?

    經測試,以上分頁方法比使用臨時表分頁速度還要快,并且簡單易用.

    方法二:

    大數據量下的分頁

    ??? 對于非常大的數據模型而言,分頁檢索時,每次都加載整個數據源非常浪費。通常的選擇是檢索頁面大小的塊區的數據,而非檢索所有的數據,然后單步執行當前行。

    ??? 本文演示ASP.net的DataGrid和Sql Server 實現大數據量下的分頁,為了便于實現演示,數據表采用了Northwind數據庫的Orders表(830條記錄)。

    ??? 如果數據表中有唯一的自增索引,并且這個字段沒有出現斷號現象。檢索頁面大小的塊區數據就非常簡單了。通過簡單的Sql語句就可以實現這個功能:

    ??? select * from orders where orderid between 10248 and 10253

    ??? 其中,開始編號為:(CurrentPageIndex - 1) * PageSize? 結束編號為:CurrentPageIndex * PageSize

    ??? 當然,如果這個字段斷號不是很嚴重,而且允許不是很嚴格的按照每頁條數分頁,這樣的方法也是可以用的。

    ??? 如果這個字段斷號,或者需要按照其他條件排序分頁,就要復雜些了。首先要獲得這個頁面需要顯示的編號,然后再按照這個編號獲得需要的塊區數據。根據編號獲得塊區數據很簡單。不過用下面方式獲得數據排序并不是按照指定的id列表順序,這時候還要附加order by 命令。

    select * from orders where orderid in (10248,10249,10250,10251,10252,10253) order by orderid desc

    ??? 獲得這個頁面需要顯示的編號列表就復雜多了,而且有多種方案:

    方案一:維護一個表,這個表記錄需要顯示的這些編號排序順序。(這個表可以是臨時表,也可以是物理表)。下面演示了利用一個全局臨時表。這個全局臨時表記錄需要顯示的編號。注意排序,這里的order by 就是需要顯示的排序順序。

    create table ##temptable(iid int IDENTITY (1, 1) NOT NULL,mainid int NOT NULL)insert ##temptable(mainid) select OrderID from orders order by OrderID descselect * from ##temptabledrop table ##temptable -- 實際執行時候,刪除全部臨時表當然不再這里執行。

    這個臨時表存在,獲得指定分頁的分塊數據就很簡單了。看下面代碼:

    create table ##temptable(iid int IDENTITY (1, 1) NOT NULL,mainid int NOT NULL)insert ##temptable(mainid) select OrderID from orders order by OrderID descdeclare @PageSize int,@CurrPage int,@strSQL varchar(2000),@IDStr varchar(1000)select @PageSize = 30select @CurrPage = 2select @IDStr = ''select @IDStr = @IDStr + ltrim(rtrim(str(MainID))) + ',' from ##temptable where iid between ((@CurrPage-1)*@PageSize+1) and @CurrPage*@PageSizeif @IDStr <> '' begin select @IDStr = left(@IDStr,len(@IDStr)-1)endselect @strSQL = 'select * from orders where OrderID in ('+@IDStr+')? order by OrderID desc 'exec(@strSQL)drop table ##temptable

    注意:實際使用這個方案的時候,還要考慮何時更新這個全局臨時表,一般是放到計劃任務中,定時更新這個匯總表。

    方案二:每次都去查詢,每次獲得最新的編號順序。由于這時候不存在這個臨時表,書寫獲得需要顯示頁面的編號的字符串就需要點技巧,看下面的代碼: ASP.net 的 DataGrid 提供了使用這種分區的數據的方法。 DataGrid 通過 AllowCustomPaging 和 VirtualItemCount 屬性支持塊區操作。如果 AllowCustomPaging 為 true,則 DataGrid 不會根據 CurrentPageIndex 計算數據模型中的起始顯示位置。DataGrid 將顯示數據模型中的所有數據,而頁導航欄將當前位置報告為 (VirtualItemCount+PageSize-1)/PageSize 之 CurrentPageIndex 頁。下面的示例說明此功能。

    declare @PageSize int,@CurrPage int,@topnum int,@previous intselect @PageSize = 30select @CurrPage = 2select @topnum = @CurrPage * @PageSizeselect @previous = (@CurrPage - 1) * @PageSizedeclare @i int,@IDStr nvarchar(500),@strSQL nvarchar(1000)select @i = 0select @strSQL = N''select @strSQL = @strSQL + N' select top '+str(@topnum)+ ' @i = @i + 1 'select @strSQL = @strSQL + N',? @IdStr = 'select @strSQL = @strSQL + N'case when @i > '+str(@previous)+' then? @IdStr + ltrim(rtrim(str(OrderID))) + '','' 'select @strSQL = @strSQL + N'else N''''end 'select @strSQL = @strSQL + N'from Orders 'select @strSQL = ltrim(rtrim(@strSQL)) + N' order by OrderID desc 'Select @IdStr = N''exec sp_executesql @strSQL,N'@i int,@IdStr varchar(500) output',@i,@IdStr outputif len(rtrim(ltrim(@IdStr))) > 0begin select @IdStr = left(@IdStr,len(@IdStr)-1)endselect @strSQL = 'select * from orders where OrderID in ('+@IDStr+')'exec(@strSQL)

    ?

    ???? protected void BindDataGrid(int currpage) {? string strConn = "Data Source=(local);Integrated Security=SSPI;database=Northwind";? // 請確認 機器名/ASPNET 用戶可以訪問Northwind數據庫? SqlCommand cmd = new SqlCommand();? SqlConnection conn = new SqlConnection(strConn);? SqlParameter[]? parms = new SqlParameter[] {?? new SqlParameter("@PageSize",SqlDbType.Int),?? new SqlParameter("@CurrPage",SqlDbType.Int),?? new SqlParameter("@SearchSql",SqlDbType.NVarChar,128),?? new SqlParameter("@Count",SqlDbType.Int),? };? parms[0].Value = DataGrid1.PageSize;? parms[1].Value = (currpage+1);?? //? 數據庫的分頁算法第一頁是1? DataGrid的第一頁是0? parms[2].Value = DBNull.Value;? parms[3].Direction = ParameterDirection.Output;? parms[3].Value = DBNull.Value;? DataSet DS = new DataSet();? try?? {?? if (conn.State != ConnectionState.Open) conn.Open();?? cmd.Connection = conn;?? cmd.CommandText = "Selected_Page_List";?? cmd.CommandType = CommandType.StoredProcedure;?? if (parms != null)??? {??? foreach (SqlParameter parm in parms)???? cmd.Parameters.Add(parm);?? }?? SqlDataAdapter DA = new SqlDataAdapter(cmd);?? DA.Fill(DS);?? int aa = Convert.ToInt32(parms[3].Value.ToString());?? cmd.Parameters.Clear();?? if (currpage == 0)?? {??? DataGrid1.VirtualItemCount = aa;?? }?? DataGrid1.CurrentPageIndex = currpage;?? DataGrid1.DataSource = DS;?? DataGrid1.DataBind();? }? catch(Exception ewx)? {?? conn.Close();?? Response.Write (ewx.Message.ToString());?? Response.End();? } }??? void Page_Load(Object sender, EventArgs E ) {? if (!IsPostBack)?? {?? BindDataGrid(0);?? // 第一次打開這個頁面,訪問分頁的第一頁? }??? }??? void MyDataGrid_Page(Object sender, DataGridPageChangedEventArgs e) {? BindDataGrid(e.NewPageIndex);??? }

    如果你有更多數據量的表稍加修改,也可以使用本演示程序。其下是演示代碼下載,演示代碼使用的是方案二。使用方法看readme.txt文件。

    整個演示代碼 下載

    http://chs.gotdotnet.com/quickstart/aspplus/samples/webforms/ctrlref/webctrl/datagrid/doc_datagrid.aspx#paging
    這里演示了利用DataGrid 的這個功能(沒有本文中討論的利用存儲過程獲得分區數據)。如對DataGrid的這個功能不太熟悉,請先看這里。

    ?

    方法三:

    雖然 DataGrid 控件自己帶了一個分頁處理機制,但它是將符合查詢條件的所有記錄讀入內存,然后進行分頁顯示的。隨著符合條件的記錄數目增多,就會出現運行效率問題,或者至少是資源的利用率下降。

    下面的代碼示例都以下面的表結構為準:

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

    SQL Server / Access 等微軟產品中,我們通常的自定義分頁有兩種思路:

    一種是以 ASP.NET Forum 為代表的、“臨時表”方法:即在存儲過程中建立一個臨時表,該臨時表包含一個序號字段(1,2,3,....)以及表的主鍵(其他能夠唯一確定一行記錄的字段也是可以的)字段。存儲過程可能如下:(編號 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 語句:用兩次 TOP 命令取得我們所要的分頁數據,例如:(編號 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

    這個的想法就是“掐頭去尾”,還有不少分頁的方法,這里就不一一列出了。

    對于 Oracle 數據庫,有幾處不同嚴重妨礙了上面幾個方法的實施,比如,Oracle 不支持 TOP 關鍵字:不過這個好像并不十分嚴重,因為它提供了 rownum 這個隱式游標,可以實現與 TOP 類似的功能,如:
    SELECT TOP 10 ... FROM WHERE ...

    要寫成
    SELECT ... FROM ... WHERE ... AND rownum <= 10

    rownum 是記錄序號(1,2,3...),但有一個比較麻煩的事情是:如果 SQL 語句中有 ORDER BY ... 排序的時候,rownum 居然是先“標號”后排序!這樣,這個序號如果不加處理是不合乎使用需求的。

    至于臨時表,Oracle 的臨時表和 SQL Server 的有很大不同,我還沒搞懂這個東西,就不妄加揣測了。

    國內網站中介紹 Oracle 分頁的資料很少,我找到了一個國外站點(www.faqts.com)的一篇 FAQ,根據這篇文章的介紹,可以如下分頁:(編號 Ora1)
    SELECT * FROM
    ???? (
    ???? SELECT A.*, rownum r
    ???? FROM
    ????????? (
    ????????? SELECT *
    ????????? FROM Articles
    ????????? ORDER BY PubTime DESC
    ????????? ) A
    ???? WHERE rownum <= PageUpperBound
    ???? ) B
    WHERE r > PageLowerBound;

    其中藍色部分可以改為任意的、需要的 SQL SELECT 語句,這點倒是挺方便的。

    方法四:

    今天突然發現,Oracle原來可以這樣實現分頁功能:

    select * from (select rownum rdd,field1,field2 from t_table where rownum<=400) where? rdd>200

    上述語句實現了從第201條記錄開始處取200條記錄

    posted on 2007-02-21 13:50 JAVA_UFO 閱讀(765) 評論(0)  編輯  收藏 所屬分類: sqlserver and Orcale


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    導航

    統計

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 日韩电影免费在线| 巨波霸乳在线永久免费视频 | 最近中文字幕mv手机免费高清| 亚洲AV无码久久精品色欲| a级成人免费毛片完整版| 亚洲av无码一区二区三区不卡| a在线观看免费视频| 亚洲性天天干天天摸| 精品一区二区三区无码免费视频| 精品亚洲成AV人在线观看| 999任你躁在线精品免费不卡| 亚洲视频在线观看免费视频| 无人在线直播免费观看| 亚洲精品久久久久无码AV片软件| 热久久精品免费视频| 一区二区三区视频免费| 亚洲精品无码Av人在线观看国产| 91精品国产免费入口| 亚洲欧洲日韩国产一区二区三区| 国产特级淫片免费看| 一级中文字幕乱码免费| 亚洲国产成人私人影院| 国产乱码免费卡1卡二卡3卡| 日本亚洲高清乱码中文在线观看 | 国产国产人免费人成免费视频| 黄页网站在线视频免费| 亚洲国产AV无码专区亚洲AV| 日韩欧毛片免费视频| 亚洲国产AV一区二区三区四区| 亚洲女同成人AⅤ人片在线观看| 美女视频黄a视频全免费网站色窝 美女被cao网站免费看在线看 | 亚洲乱码在线播放| 免费大香伊蕉在人线国产 | 亚洲成人高清在线观看| 国产精品国产免费无码专区不卡 | 男人免费视频一区二区在线观看| 亚洲成AV人片在线播放无码| 成人免费淫片在线费观看| 久久久WWW成人免费精品| 亚洲AV无码成人专区| 国产成人亚洲影院在线观看|