Mỗi kỹ thuật phân trang đều có những ưu điểm, nhược điểm. Tôi thì sử dụng
phân trang bằng kỹ thuật SQL server ở phần trình bày
hiển thị trên giao diện web vì ở đây sẽ có nhiều người xem, còn dùng các tools
có sẵn trong các phần quản trị. Bài viết này Tôi giới thiệu thuật
toán trang bằng SQL và sẽ làm ví dụ demo trong trang Aspx
Bạn truy cập chiencong.com bạn xẽ thấy phân trang của tôi dạng:
Trang đầu … 1 2 3
[4] 5 6 7 … Trang cuối tức là ta có trang 4 là trang đang xem, các liên kết
đến trang đầu, trang cuối và hiển thị 7 trang cho mỗi phân đoạn trang. Ta sẽ
viết hàm SQL để truyền vào các tham số:
@Total int – Tổng số bản ghi theo điều kiện truy vấn,
@currPage int – Trang bạn đang xem,
@PageSize int – Số trang hiển thị cho mỗi phân đoạn trang,
@rowperpage int – Số bản ghi hiển thị trên trang
CREATE Function [dbo].[fPhanTrangSQL]( @Total int, @currPage int , @PageSize int, @rowperpage int ) Returns nvarchar(1000) AS Begin If @currPage=0 Set @currPage=1 DECLARE @PageNumber int SET @PageNumber=1 DECLARE @i int SET @i=1 DECLARE @TotalPage int IF @Total%@rowperpage>0 SET @TotalPage=(@Total/@rowperpage)+1 ELSE SET @TotalPage=@Total/@rowperpage DECLARE @Start int SET @Start=0 DECLARE @SQL nvarchar(4000) SET @SQL='' If @TotalPage >1 BEGIN SET @SQL=@SQL+ N'<div id=''paging''> Trang: ' IF @currPage<=@TotalPage BEGIN IF @currPage=1 BEGIN SET @PageNumber=@PageSize IF @PageNumber>@TotalPage SET @PageNumber=@TotalPage SET @Start=1 END ELSE BEGIN SET @SQL=@SQL+ N' <a href=''?page=1''> Trang đầu </a> ' SET @SQL=@SQL+ ' <a href=?page='+ Cast((@currPage-1) AS nvarchar(4))+N'>«</a> ' IF(@TotalPage-@currPage)<@PageSize/2 BEGIN SET @Start=(@TotalPage-@PageSize)+1 IF @Start<=0 SET @Start=1 SET @PageNumber = @TotalPage END ELSE BEGIN IF (@currPage-(@PageSize/2))=0 BEGIN SET @Start=1 SET @PageNumber=@currPage+(@PageSize/2)+1 IF @TotalPage<@PageNumber SET @PageNumber=@TotalPage END ELSE BEGIN SET @Start=@currPage-(@PageSize/2) IF @Start<=0 SET @Start=1 SET @PageNumber=@currPage+(@PageSize/2) IF @TotalPage<@PageNumber SET @PageNumber=@TotalPage ELSE IF @PageNumber <@PageSize SET @PageNumber=@PageSize END END END SET @i=@Start WHILE @i<=@PageNumber BEGIN IF @i=@currPage SET @SQL=@SQL+'[<b>'+Cast(Cast(@i AS int) AS nvarchar(4))+'</b>]' ELSE SET @SQL=@SQL+'<a href=''?page='+Cast(@i AS nvarchar(4))+'''>' +Cast(@i AS nvarchar(4))+'</a> ' SET @i=@i+1 END IF @currPage<@TotalPage BEGIN SET @SQL=@SQL+ N'<a href=''?page='+Cast((@currPage+1) AS nvarchar(4))+N'''>»</a> ' SET @SQL=@SQL+ N' <a href=''?page='+cast(@TotalPage AS nvarchar(6))+ N'''> Trang cuối </a>' End Set @SQL=@SQL+'</div>' End END Return @SQL END
Kết quả trả về của hàm này là chuỗi Nvarchar và khi ta thực thi hàm này sẽ cho ta mã html hiển thị phân trang. Tiếp theo ta sẽ viết Store procedure thực hiện phân trang dữ liệu, sử dụng hàm trên. Giả sử tôi có bảng TB_News có các trường cơ bản là idNews, CateID, Title, Descript, Content
Store phân trang với các bản tin lấy theo CateID như sau
CREATE PROCEDURE TB_News_PagingByCateID @currPage int, @recodperpage int, @Pagesize int, @CateID int AS BEGIN DECLARE @Tolal int Begin WITH s AS ( SELECT ROW_NUMBER() OVER(ORDER BY tn.idNews desc) As RowNum, tn.idNews, tn.CateID, tn.Title, tn.Descript FROM TB_News tn Where tn.CateID=@CateID ) Select * From s Where RowNum Between (@currPage - 1)*@recodperpage+1 AND @currPage*@recodperpage END -- Tính tổng số bản ghi SELECT @Tolal=Count(*) FROM TB_News Where CateID=@CateID --Gọi hàm phân trang Select dbo.fPhanTrangSQL(@Tolal, @currPage, @Pagesize, @recodperpage) As Paging END
Demo trong trang ASP.net sử dụng kỹ thuật này. Tôi sẽ minh họa
với DataList và hiển thị dữ liệu 2 cột – Với các control khác như Gridview,
ListView, Repeater cách làm cũng tương tự:
Video clip hướng dẫn thực hiện chi tiết:
Trong trang aspx bạn cần tạo một ListView như sau:
<asp:DataList ID="lvListNew" runat="server" RepeatColumns="2" CellPadding="10" CellSpacing="10" RepeatDirection="Horizontal"> <ItemStyle Width="50%" HorizontalAlign="Left" VerticalAlign="Top" /> <ItemTemplate> <a href='http://hmclip.net/?newid=<%# Eval("idNews") %>' title='<%# Eval("Title") %>'><%# Eval("Title") %></a><br /> <%# Eval("Description") %> <a href='http://hmclip.net/?newid=<%# Eval("idNews") %>' title='<%# Eval("Title") %>' class="Xemtiep">Xem tiếp ...</a> </ItemTemplate> <FooterTemplate> <div class="paging"><%=strPaging %></div> </FooterTemplate> </asp:DataList>
Trong code C# ta cần viết hàm kết nối dữ liệu và thực thị Store trả vể
DataSet như sau:
private DataSet GetPhanTrang_DataSet( string strTenStore, int currentPage, int recordPerpage, int pageSize, int CateID) { string strConnect = @"Server =.\SQL2005;Initial Catalog=YourDatabase;User ID=sa;Password=***"; DataSet ds = new DataSet(); SqlConnection sqlCn = new SqlConnection(strConnect); try { //Mo ket noi sqlCn.Open(); SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCn; sqlCmd.CommandType = CommandType.StoredProcedure; sqlCmd.CommandText = strTenStore; sqlCmd.Parameters.Add(new SqlParameter("@currPage", currentPage)); sqlCmd.Parameters.Add(new SqlParameter("@recodperpage", recordPerpage)); sqlCmd.Parameters.Add(new SqlParameter("@Pagesize", pageSize)); sqlCmd.Parameters.Add(new SqlParameter("@CateID", CateID)); SqlDataAdapter sqlDa = new SqlDataAdapter(); sqlDa.SelectCommand = sqlCmd; sqlDa.Fill(ds); } catch { } finally { if (sqlCn.State == ConnectionState.Open) sqlCn.Close(); sqlCn.Dispose(); } return ds; }
Code hiển thị dữ liệu:
public string strPaging = ""; private int page = 0; protected void Page_Load(object sender, EventArgs e) { page = (Request.QueryString["page"] + "" != "") ? int.Parse("0" + Request.QueryString["page"]) : 1; DataSet ds = GetPhanTrang_DataSet("TB_News_PagingByCateID", page, 10, 7, 94); if (ds.Tables.Count > 0) { if (ds.Tables[0].Rows.Count > 0) { lvListNew.DataSource = ds.Tables[0]; lvListNew.DataBind(); } if (ds.Tables[1].Rows.Count > 0) { strPaging = ds.Tables[1].Rows[0][0] + ""; } } }
Nguồn: h m c l i p . n e t