前端佈局
<table style="width:100%">
<tr><td>搜索:<asp:TextBox ID="TextBox1" runat="server"/> <asp:Button ID="Button1" Text="搜索" OnClick="Button1_Click"/></td></tr>
<tr><td><div id="divmain" runat="server"></div></td></tr>
<tr><td>
<asp:Button ID="btnFirst" Text="首頁" OnClick="btnFirst_Click"/>
<asp:Button ID="btnPro" Text="上一頁" OnClick="btnPro_Click"/>
<asp:Button ID="btnNext" Text="下一頁" OnClick="btnNext_Click"/>
<asp:Button ID="btnLast" Text="末頁" OnClick="btnLast_Click"/>
<asp:Label ID="labCountPage" runat="server"/> <asp:Label ID="labpage" runat="server"/>
<asp:TextBox ID="TextBox2" Width="16px"/> <asp:Button ID="btnGo" Text="Go" OnClick="btnGo_Click"/>
</td></tr>
</table>
後台核心邏輯
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) { ViewState["pageIndex"] = 1; DataPage(); }
}
private void DataPage()
{
string constr = "data source=.;initial catalog=News;user id=sa;password=111111;";
using (var conn = new SqlConnection(constr))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
// 子查詢分頁:每頁 2 條
cmd.CommandText = @"select top 2 * from (select * from T_News where NewsTitle like @title) as t
where t.Id not in (select top ((@pageIndex-1)*2) t.Id from (select * from T_News where NewsTitle like @title) as t)
order by t.Id";
cmd.Parameters.AddWithValue("@pageIndex", ViewState["pageIndex"]);
cmd.Parameters.AddWithValue("@title", "%" + TextBox1.Text.Trim() + "%");
var dt = new DataTable();
new SqlDataAdapter(cmd).Fill(dt);
// 總記錄數
cmd.CommandText = "select count(*) from T_News where NewsTitle like @titles";
cmd.Parameters.AddWithValue("@titles", "%" + TextBox1.Text.Trim() + "%");
int sum = (int)cmd.ExecuteScalar();
ViewState["pageCount"] = (sum % 2 == 0) ? sum / 2 : sum / 2 + 1;
// 構建 HTML Table
var sb = new StringBuilder("<table>");
foreach (DataRow row in dt.Rows)
{
sb.AppendFormat("<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>",
row["NewsTitle"], row["NewsContent"], row["CreateTime"]);
}
sb.Append("</table>");
divmain.InnerHtml = sb.ToString();
labCountPage.Text = "總共 " + ViewState["pageCount"] + " 頁";
labpage.Text = "當前第 " + ViewState["pageIndex"] + " 頁";
}
}
// 分頁按鈕事件:修改 ViewState["pageIndex"] 並重新綁定
protected void btnFirst_Click(...) { ViewState["pageIndex"] = 1; DataPage(); }
protected void btnPro_Click(...) { int i=(int)ViewState["pageIndex"]; if(i>1){ViewState["pageIndex"]=i-1;DataPage();} }
protected void btnNext_Click(...) { int i=(int)ViewState["pageIndex"]; if(i<(int)ViewState["pageCount"]){ViewState["pageIndex"]=i+1;DataPage();} }
protected void btnLast_Click(...) { ViewState["pageIndex"]=ViewState["pageCount"]; DataPage(); }
protected void btnGo_Click(...) { int i=int.Parse(TextBox2.Text); if(i>0 && i<=(int)ViewState["pageCount"]){ViewState["pageIndex"]=i;DataPage();} }
protected void Button1_Click(...) { ViewState["pageIndex"]=1; DataPage(); }
優化建議
- 分頁 SQL 建議改用
ROW_NUMBER() OVER (ORDER BY Id) + OFFSET/FETCH (SQL Server 2012+) 或 OFFSET @offset ROWS FETCH NEXT @pageSize ROWS ONLY,性能更優、語法更清晰。
- 使用參數化查詢已防注入,但連接字符串應放入
web.config。
- 大數據量時,
StringBuilder 拼接 HTML 可接受;極大數據建議用 Repeater/GridView 等數據綁定控件。
- ViewState 存儲分頁狀態會增加頁面體積,可改用 QueryString 或 Session。