• 主页
  • ASP
  • .NET Framework
  • Web Services
  • VB
  • VC
  • 图表区
  • 分析与设计
  • 组件/控件开发
  • LINQ

谁能提供一份关于存储过程分页的全代码,想学习学习!

sea76 2004-12-23 11:16:49
asp.net 调用代码也要。谢谢
...全文
203 点赞 收藏 13
写回复
13 条回复
morality 2004年12月23日
--作者:绉建 有一通用的存储过程,请大家对比一下各自的优劣

CREATE Proc GetPageRecord2
@QueryStr nvarchar(4000),--表名、视图名、查询语句
@PageSize int=10,--每页的大小(行数)
@PageCurrent int=1,--要显示的页
@FdShow nvarchar (4000)='',--要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段
@FdOrder nvarchar (1000)='',--排序字段列表
@Key nvarchar (100)=''--标识列名称
as
declare @FdName nvarchar(250)--表中的主键或表、临时表中的标识列名
,@Id1 varchar(20),@Id2 varchar(20)--开始和结束的记录号
,@Obj_ID int--对象ID
--表中有复合主键的处理
declare @strfd nvarchar(2000)--复合主键列表
,@strjoin nvarchar(4000)--连接字段
,@strwhere nvarchar(2000)--查询条件


select @Obj_ID=object_id(@QueryStr)
,@FdShow=case isnull(@FdShow,'') when '' then ' *' else ' '+@FdShow end
,@FdOrder=case isnull(@FdOrder,'') when '' then '' else ' order by '+@FdOrder end
,@QueryStr=case when @Obj_ID is not null then ' '+@QueryStr else ' ('+@QueryStr+') a' end

--如果显示第一页,可以直接用top来完成
if @PageCurrent=1
begin
select @Id1=cast(@PageSize as varchar(20))
exec('select top '+@Id1+@FdShow+' from '+@QueryStr+@FdOrder)
return
end


--如果是表,则检查表中是否有标识更或主键
if @Obj_ID is not null and objectproperty(@Obj_ID,'IsTable')=1 or len(@Key)>0
begin
select @Id1=cast(@PageSize as varchar(20))
,@Id2=cast((@PageCurrent-1)*@PageSize as varchar(20))

if len(@Key)>0
begin
select @FdName=@Key
goto lbuseidentity
end
select @FdName=name from syscolumns where id=@Obj_ID and status=0x80
if @@rowcount=0--如果表中无标识列,则检查表中是否有主键
begin
if not exists(select 1 from sysobjects where parent_obj=@Obj_ID and xtype='PK')
goto lbusetemp--如果表中无主键,则用临时表处理

select @FdName=name from syscolumns where id=@Obj_ID and colid in(
select colid from sysindexkeys where @Obj_ID=id and indid in(
select indid from sysindexes where @Obj_ID=id and name in(
select name from sysobjects where xtype='PK' and parent_obj=@Obj_ID
)))
if @@rowcount>1--检查表中的主键是否为复合主键
begin
select @strfd='',@strjoin='',@strwhere=''
select @strfd=@strfd+',['+name+']'
,@strjoin=@strjoin+' and a.['+name+']=b.['+name+']'
,@strwhere=@strwhere+' and b.['+name+'] is null'
from syscolumns where id=@Obj_ID and colid in(
select colid from sysindexkeys where @Obj_ID=id and indid in(
select indid from sysindexes where @Obj_ID=id and name in(
select name from sysobjects where xtype='PK' and parent_obj=@Obj_ID
)))
select @strfd=substring(@strfd,2,2000)
,@strjoin=substring(@strjoin,5,4000)
,@strwhere=substring(@strwhere,5,4000)
goto lbusepk
end
end
else
goto lbuseidentity
end
else
goto lbusetemp

/*--使用标识列或主键为单一字段的处理方法--*/
lbuseidentity:
exec('select top '+@Id1+@FdShow+' from '+@QueryStr
+' where '+@FdName+' not in (select top '
+@Id2+' '+@FdName+' from '+@QueryStr+@FdOrder
+')'+@FdOrder
)


return


/*--表中有复合主键的处理方法--*/
lbusepk:
exec('select '+@FdShow+' from(select top '+@Id1+' a.* from
(select top 100 percent * from '+@QueryStr+@FdOrder+') a
left join (select top '+@Id2+' '+@strfd+'
from '+@QueryStr+@FdOrder+') b on '+@strjoin+'
where '+@strwhere+') a'
)
return

/*--用临时表处理的方法--*/
lbusetemp:
select @FdName='[ID_'+cast(newid() as varchar(40))+']'
,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(20))
,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(20))

exec('select '+@FdName+'=identity(int,0,1),'+@FdShow+'
into #tb from'+@QueryStr+@FdOrder+'
select '+@FdShow+' from #tb where '+@FdName+' between '
+@Id1+' and '+@Id2
)


GO
回复 点赞
morality 2004年12月23日
http://blog.csdn.net/wellknow/archive/2004/07/29/55167.aspx
回复 点赞
morality 2004年12月23日
参见:
http://blog.csdn.net/pbsql/archive/2004/11/30/199657.aspx
回复 点赞
sea76 2004年12月23日
还有没有了,一会结贴了
回复 点赞
sea76 2004年12月23日
不好意思
回复 点赞
luluso 2004年12月23日
上面的不是???存储过程+在.net在调用的方法..你看仔细点.
回复 点赞
sea76 2004年12月23日
楼上的,有没有调用代码
回复 点赞
luluso 2004年12月23日
CREATE PROCEDURE GetRecordFromPage
@tblName varchar(255), -- 表名
@fldName varchar(255), -- 字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@IsCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1000) = '' -- 查询条件 (注意: 不要加 where)
AS

declare @strSQL varchar(2000) -- 主语句
declare @strTmp varchar(1000) -- 临时变量
declare @strOrder varchar(1000) -- 排序类型

if @OrderType != 0
begin
set @strTmp = "<(select min"
set @strOrder = " order by [" + @fldName +"] desc"
end
else
begin
set @strTmp = ">(select max"
set @strOrder = " order by [" + @fldName +"] asc"
end

set @strSQL = "select top " + str(@PageSize) + " * from ["
+ @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
+ @strOrder

if @strWhere != ''
set @strSQL = "select top " + str(@PageSize) + " * from ["
+ @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @fldName + "] from [" + @tblName + "] where (" + @strWhere + ") "
+ @strOrder + ") as tblTmp) and (" + @strWhere + ") " + @strOrder

if @PageIndex = 1
begin
set @strTmp = ""
if @strWhere != ''
set @strTmp = " where (" + @strWhere + ")"

set @strSQL = "select top " + str(@PageSize) + " * from ["
+ @tblName + "]" + @strTmp + " " + @strOrder
end

if @IsCount != 0
set @strSQL = "select count(*) as Total from [" + @tblName + "]"

exec (@strSQL)
GO

要注意看,修改后的存储过程在使用@strWhere时,都在其前后加上了(),这样,就防止嵌套的()出现错误

下面的代码是引用该存储过程的一个范例

SqlConnection MyConnection=new SqlConnection(ConfigurationSettings.AppSettings["dsn"]);
DataSet MyDataSet=new DataSet();
string strKeyword=Keyword.Text.Trim().Replace("\'","\'\'");
string strSalesId=Sales.SelectedItem.Value;
int RecordCount=CalcRecordCount();
RecordNumber.Text=RecordCount.ToString();
LblRecordNumber.Text=RecordCount.ToString();
string strExpress="Id<>0";
if (strKeyword!="")
strExpress=strExpress+" and (companyenname like '%"+strKeyword+"%' or companychname like '%"+strKeyword+"%' or Companyshortname like '%"+strKeyword+"%' or web like '%"+strKeyword+"%' or mainproduct like '%"+strKeyword+"%' or phone like '%"+strKeyword+"%' or memo like '%"+strKeyword+"%' or address like '%"+strKeyword+"%' or linkmanphone like '%"+strKeyword+"%')";
if (strSalesId!="")
strExpress=strExpress+" and salesid="+strSalesId;
SqlCommand MyCommand=new SqlCommand();
MyCommand.Connection=MyConnection;
MyCommand.CommandText="GetRecordFromPage";
MyCommand.CommandType=CommandType.StoredProcedure;
MyCommand.Parameters.Add("@tblName","customerview");
MyCommand.Parameters.Add("@fldName","id");
MyCommand.Parameters.Add("@strWhere",strExpress);
MyCommand.Parameters.Add("@PageSize",Int32.Parse(CustomerList.PageSize.ToString()));
MyCommand.Parameters.Add("@PageIndex",Int32.Parse(ViewState["PageIndex"].ToString())+1);
SqlDataReader MyReader;
MyConnection.Open();
MyReader=MyCommand.ExecuteReader();
CustomerList.VirtualItemCount=RecordCount;
CustomerList.DataSource=MyReader;
CustomerList.DataKeyField="id";
CustomerList.DataBind();
MyReader.Close();
MyConnection.Close();

在这里,要注意的是存储过程使用的PAGEINDEX变量是从1开始

就算条件再复杂,也能搞定

回复 点赞
sea76 2004年12月23日
不知道还有没有了。这些我都看过
回复 点赞
KentYu 2004年12月23日
然后在新建一个aspx页面,代码如下:
<%@ Page language="c#" Codebehind="custompage.aspx.cs" AutoEventWireup="false" Inherits="cyc_test.custompage" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>custompage</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
<style>A { BEHAVIOR: url(MouseOver.htc) }
HR { COLOR: black; HEIGHT: 2px }
.StdText { FONT-WEIGHT: bold; FONT-SIZE: 9pt; FONT-FAMILY: verdana }
.StdTextBox { BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; FONT-SIZE: 9pt; FILTER: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true'); BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid; FONT-FAMILY: verdana }
.Shadow { FILTER: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true') }
</style>
</HEAD>
<body style="FONT-FAMILY: arial" bgColor="ivory" MS_POSITIONING="GridLayout">
<form id="custompage" method="post" runat="server">
<h2>项目总结之datagrid自定义分页篇
</h2>
<asp:label id="Label1" runat="server" font-bold="true" cssclass="StdText">当前路径: </asp:label><asp:label id="lblURL" style="COLOR: blue" runat="server" cssclass="StdText"></asp:label>
<!-- Query --><br/>
<asp:label id="Label2" runat="server" cssclass="stdtext" Text="查询语句:"></asp:label>
<asp:textbox id="Textbox1" runat="server" cssclass="stdtextbox" text="SELECT employeeid, firstname, lastname,title FROM Employees where employeeid>0 order by employeeid" width="765px" Enabled="false"></asp:textbox>
<hr>
<!-- Show the information -->
<asp:datagrid id="grid" runat="server" OnPageIndexChanged="PageIndexChanged" AllowCustomPaging="True" AllowPaging="True" PageSize="5" BorderWidth="1" BorderColor="black" BorderStyle="solid" BackColor="White" CssClass="Shadow" GridLines="vertical" CellSpacing="0" CellPadding="2" Font-Names="Verdana" Font-Size="Smaller">
<PagerStyle Font-Bold="true" Mode="NumericPages" BackColor="palegreen" />
<AlternatingItemStyle BackColor="#eeeeee" />
<ItemStyle BackColor="White" />
<HeaderStyle Font-Bold="True" ForeColor="White" BackColor="Navy" />
</asp:datagrid></form>
</body>
</HTML>




再写后台的源代码:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;

namespace cyc_test
{
/// <summary>
/// custompage 的摘要说明。
/// </summary>
public class custompage : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Label lblURL;
protected System.Web.UI.WebControls.Label Label2;
protected System.Web.UI.WebControls.TextBox Textbox1;
protected System.Web.UI.WebControls.DataGrid grid;

private void Page_Load(object sender, System.EventArgs e)
{
// 第一次加载页时,初始化
if (!Page.IsPostBack)
{
lblURL.Text = Request.Url + "<hr>";
createdatasource(1);
}
}

//绑定datagrid的函数
protected void createdatasource(int current_page)
{
string str_table_name,str_column_list,str_order_column,str_condition;
//查询的表名
str_table_name="employees";
//返回的列名列表
str_column_list="employeeid,firstname,lastname,title";
//排序列的列名
str_order_column="employeeid";
//查询的表件
str_condition="employeeid>0";
string strConn = "DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;";
SqlConnection conn = new SqlConnection(strConn);
//声明执行存储过程的SqlCommand
SqlCommand scd_sel=new SqlCommand("up_custompage",conn);
scd_sel.CommandType=CommandType.StoredProcedure;
//给存储过程的参数赋值
SqlParameter sp_temp;
sp_temp=scd_sel.Parameters.Add("@vc_order_column_name",SqlDbType.VarChar,100);
sp_temp.Direction=ParameterDirection.Input;
sp_temp.Value=str_order_column;
sp_temp=scd_sel.Parameters.Add("@vc_select_column_list",SqlDbType.VarChar,100);
sp_temp.Direction=ParameterDirection.Input;
sp_temp.Value=str_column_list;
sp_temp=scd_sel.Parameters.Add("@vc_select_table_list",SqlDbType.VarChar,100);
sp_temp.Direction=ParameterDirection.Input;
sp_temp.Value=str_table_name;
sp_temp=scd_sel.Parameters.Add("@vc_condition",SqlDbType.VarChar,100);
sp_temp.Direction=ParameterDirection.Input;
sp_temp.Value=str_condition;
sp_temp=scd_sel.Parameters.Add("@page_size",SqlDbType.Int);
sp_temp.Direction=ParameterDirection.Input;
sp_temp.Value=grid.PageSize;
sp_temp=scd_sel.Parameters.Add("@current_page",SqlDbType.Int);
sp_temp.Direction=ParameterDirection.Input;
sp_temp.Value=current_page;
sp_temp=scd_sel.Parameters.Add("@total1",SqlDbType.Int);
sp_temp.Direction=ParameterDirection.Output;

//执行存储过程
SqlDataAdapter sda=new SqlDataAdapter();
sda.SelectCommand=scd_sel;
if (conn.State==ConnectionState.Closed)
conn.Open();
DataSet ds=new DataSet();
sda.Fill(ds,"tb1");
conn.Close();
//设置VirtualItemCount属性
grid.VirtualItemCount=(int)scd_sel.Parameters["@total1"].Value;
//绑定数据源
grid.DataSource=ds.Tables["tb1"].DefaultView;
grid.DataBind();
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN:该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.grid.ItemCreated += new System.Web.UI.WebControls.DataGridItemEventHandler(this.grid_ItemCreated);
this.grid.PageIndexChanged += new System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.PageIndexChanged);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
//datagrid的ItemCreated事件,用于定制分页导航行
private void grid_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{

ListItemType elemType = e.Item.ItemType;
//定制分页导航行,样式为[1] [2] 第 3 页 [4]
if (elemType == ListItemType.Pager)
{

TableCell pager = (TableCell) e.Item.Controls[0];

for (int i=0; i<pager.Controls.Count; i+=2)
{
Object o = pager.Controls[i];
if (o is LinkButton)
{
LinkButton h = (LinkButton) o;
h.Text = "[ " + h.Text + " ]";
}
else
{
Label l = (Label) o;
l.Text = "第" + l.Text + “页”;
}
}
}
}
//页选中(分页)事件
public void PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
{
grid.CurrentPageIndex = e.NewPageIndex;
//页码值是从零开始的,所以要加一
createdatasource(grid.CurrentPageIndex+1);
}
}
}
回复 点赞
KentYu 2004年12月23日
datagrid自定义分页是datagrid的一个重要的功能,datagrid自定义分页主要用于数据源较大时。因为数据源大(记录多),加载时间长,反应慢,耗服务器的资源。而且每显示一页就要重新加载所有的数据。而如果我们用自定义分页,则每一次只加载一页的记录,也就是只加载我们要显示的记录。这样加载数据时间短,反应快,节约服务器的资源。在做项目的过程中,我们也经常需要用到自定义功能。今天我们就说说怎样自定义分页。
先看看datagrid的自定义分页的原理,它主要依据两个主要属性,第一个就是VirtualItemCount属性,它表示datagrid一共要显示多少条记录,它就是的作用是用于生成pager(分页导航行),通过结合另外两个属性pagesize和PageButtonCount,datagrid就知道要分成多少页了及当前要显示多少个分页按钮,我们不难得到总共要显示的总页数=(VirtualItemCount+pagesize-1)/pagesize;如要总页数<PageButtonCount,则显示总页数个按钮;如果总页数>PageButtonCount,则显示PageButtonCount个按钮,当然到了最后一页就只显示VirtualItemCount% pagesize(总记录条数除以每页显示记录的余数)个按钮。另一个重要的属性就是datasource(数据源),自定义分页的一个重要的特点是显示数据源中所有的记录,如果数据源中有一条记录,则显示一条记录;如果数据源中有一万条记录,则它会显示一万条记录,可能你的机子就慢了 : )。所以自定义最重要的一点是如何设置或获取数据源了。
接下来,我们先说说自定义分页的主要步骤:
1.设置datagrid的VirtualItemCount属性;
2.获取datagrid的datasource(数据源);
3.绑定数据到datagrid;
4.设置新页的页码(datagrid.currentpageindex属性)。
重复上述2,3,4步。
下面我们以一个例子来讲解datagrid 的自定义过程。
例子要求机子装有ms sql server 7.0 或 2000,当然还要能运行asp.net页了(废话)。
我们先来写一个通用的存储过程,用于分页,返回某页的要显示的记录集,及一个输出参数--总的记录条数,但这个存储过程有缺陷,例如只能用于单表查询,必须要有条件语句等。
CREATE PROCEDURE up_custompage @vc_order_column_name varchar(100),@vc_select_column_list varchar(100),
@vc_select_table_list varchar(100),@vc_condition varchar(100),@page_size int,@current_page int,@total1 int output
/*
(
@vc_order_column_name :表要排序列的列名,只能按一列排序,而且该列必须得在输出列表中;
@vc_select_column_list :返回列的列名列表;
@vc_select_table_list:要查询的表名;
@vc_condition:查询条件的字符串,必须要有查询条列,否则会抛出异常;
@page_size:每页显示记录的条数;
@current_page:当前页的页码;
@total1:所有符合条件的记录的总数。
构造的sql语句=select top 每页显示记录的条数 * from (select top 每页显示记录的条数 返回列的列名列表 from 要查询的表名 where 要排序列的列名 in (select top 每页显示记录的条数 X 当前页的页码 要排序列的列名 from 要查询的表名 where 查询条件 order by 要排序列的列名) order by 要排序列的列名 desc ) as temp1 order by 要排序列的列名
)
*/
AS
--声明要用到的变量,@temp1是正常的分页语句字符串,@temp2是最后一页的分页语句字符串,@page_total表一共有几页,@last_page
--是最后一页的页码
declare @temp1 varchar(500),@temp2 nvarchar(500),@page_total int,@last_page int
--构造获得总页的数的检索语句
set @temp2=N'select @total2=count(*) from ' + @vc_select_table_list + ' where ' + @vc_condition
--执行检索语句,取得总的记录条数
exec sp_executesql @temp2,N' @total2 int output ',@total1 output

/*构造分页检索语句,基本原理是先取出@page_size*@current_page条记录,相当于是取出当前页及当前页前面的所有页面的记录然后取出当前面所要显示的记录,也就是反序排序后取前@page_size条记录;最后再反序排序(因为前面的顺序被反排过一次,现在再反排一次,正好是我们要的顺序),最后执行,返回结果集。
*/
if @total1>0
begin
set @page_total=(@total1+@page_size-1)/@page_size
--如果当前页不是最后一页
if @current_page<@page_total
set @temp1='select top ' + cast(@page_size as varchar(4)) + ' * from
(select top ' + cast(@page_size as varchar(4)) + ' ' + @vc_select_column_list + ' from ' + @vc_select_table_list +' where ' + @vc_order_column_name
+ ' in (select top ' + cast(@page_size*@current_page as varchar(10)) + ' ' + @vc_order_column_name + ' from ' +
@vc_select_table_list + ' where '+ @vc_condition + ' order by ' +
@vc_order_column_name + ') order by ' + @vc_order_column_name + ' DESC) as temp1 order by ' + @vc_order_column_name
else
--最后一页只返回分页后的最后几条记录,也就是@total1%@page_size条记录
begin
set @last_page=@total1%@page_size
set @temp1='select top ' + cast(@last_page as varchar(4)) + ' * from
(select top ' + cast(@last_page as varchar(4)) + ' ' + @vc_select_column_list + ' from ' + @vc_select_table_list +' where ' + @vc_order_column_name
+ ' in (select top ' + cast(@total1 as varchar(10)) + ' ' + @vc_order_column_name + ' from ' +
@vc_select_table_list + ' where '+ @vc_condition + ' order by ' +
@vc_order_column_name + ') order by ' + @vc_order_column_name + ' DESC) as temp1 order by ' + @vc_order_column_name
end
--执行检索
exec(@temp1)
end
else
return
回复 点赞
luluso 2004年12月23日
http://blog.csdn.net/21aspnet/archive/2004/10/24/149768.aspx
回复 点赞
luluso 2004年12月23日
http://blog.csdn.net/yoxking/archive/2004/12/13/214876.aspx
回复 点赞
发动态
发帖子
.NET技术社区
创建于2007-09-28

4.9w+

社区成员

66.8w+

社区内容

.NET技术交流专区
社区公告
暂无公告