02/10/2018, 20:45

Kỹ thuật phân trang dữ liệu SQL server trong trang Asp.net

Phân trang dữ liệu là đề tài được nói đến khá nhiều, Nếu dữ liệu của bạn ít bạn có thể dùng Tools có sẵn của Visual Studio, Nhưng có điều với các công cụ có sẵn này khi bạn dùng thì lệnh truy vấn dữ liệu bạn luôn phải truy vấn toàn bộ và Bind vào một control, như vậy nếu dữ liệu của bạn ...

Phân trang dữ liệu là đề tài được nói đến khá nhiều, Nếu dữ liệu của bạn ít bạn có thể dùng Tools có sẵn của Visual Studio, Nhưng có điều với các công cụ có sẵn này khi bạn dùng thì lệnh truy vấn dữ liệu bạn luôn phải truy vấn toàn bộ và Bind vào một control, như vậy nếu dữ liệu của bạn nhiều thì đây không phải là giải pháp tốt.

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 (như hmclip.net đang dùng) ở 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 hmclip 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> &nbsp;' SET @SQL=@SQL+ ' <a href=?page='+ Cast((@currPage-1) AS nvarchar(4))+N'>&laquo;</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'>&raquo;</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:thietkewebsmart.com
Bình luận
0