刚刚写的功能不错的分页存储过程,可支持多表查询,任意排序。
http://jiny-z.cnblogs.com/archive/2006/04/12/373146.html
注意:该存储过程处理逻辑被发现有严重错误,并不能实现 任意排序等功能。
/**//*
说明:1.支持多表查询 2.支持任意排序 3.不支持表别名
参考了
evafly920:[分享]千万数量级分页存储过程(效果演示)
地址:http://blog.youkuaiyun.com/evafly920/archive/2006/03/03/614813.aspx
IF(EXISTS(SELECT * FROM sysobjects WHERE [id]=OBJECT_ID('usp_PagingLarge') AND xtype='P'))
DROP PROCEDURE usp_PagingLarge
*/
GO
CREATE PROCEDURE usp_PagingLarge
@TableNames VARCHAR(200), --表名,可以是多个表,但不能用别名
@PrimaryKey VARCHAR(100), --主键,可以为空,但@Order为空时该值不能为空
@Fields VARCHAR(200), --要取出的字段,可以是多个表的字段,可以为空,为空表示select *
@PageSize INT, --每页记录数
@CurrentPage INT, --当前页,0表示第1页
@Filter VARCHAR(200) = '', --条件,可以为空,不用填 where
@Group VARCHAR(200) = '', --分组依据,可以为空,不用填 group by
@Order VARCHAR(200) = '' --排序,可以为空,为空默认按主键升序排列,不用填 order by
AS
BEGIN
DECLARE @SortColumn VARCHAR(200)
DECLARE @Operator CHAR(2)
DECLARE @SortTable VARCHAR(200)
DECLARE @SortName VARCHAR(200)
IF @Fields = ''
SET @Fields = '*'
IF @Filter = ''
SET @Filter = 'WHERE 1=1'
ELSE
SET @Filter = 'WHERE ' + @Filter
IF @Group <>''
SET @Group = 'GROUP BY ' + @Group
IF @Order <> ''
BEGIN
DECLARE @pos1 INT, @pos2 INT
SET @Order = REPLACE(REPLACE(@Order, ' asc', ' ASC'), ' desc', ' DESC')
IF CHARINDEX(' DESC', @Order) > 0
IF CHARINDEX(' ASC', @Order) > 0
BEGIN
IF CHARINDEX(' DESC', @Order) < CHARINDEX(' ASC', @Order)
SET @Operator = '<='
ELSE
SET @Operator = '>='
END
ELSE
SET @Operator = '<='
ELSE
SET @Operator = '>='
SET @SortColumn = REPLACE(REPLACE(REPLACE(@Order, ' ASC', ''), ' DESC', ''), ' ', '')
SET @pos1 = CHARINDEX(',', @SortColumn)
IF @pos1 > 0
SET @SortColumn = SUBSTRING(@SortColumn, 1, @pos1-1)
SET @pos2 = CHARINDEX('.', @SortColumn)
IF @pos2 > 0
BEGIN
SET @SortTable = SUBSTRING(@SortColumn, 1, @pos2-1)
IF @pos1 > 0
SET @SortName = SUBSTRING(@SortColumn, @pos2+1, @pos1-@pos2-1)
ELSE
SET @SortName = SUBSTRING(@SortColumn, @pos2+1, LEN(@SortColumn)-@pos2)
END
ELSE
BEGIN
SET @SortTable = @TableNames
SET @SortName = @SortColumn
END
END
ELSE
BEGIN
SET @SortColumn = @PrimaryKey
SET @SortTable = @TableNames
SET @SortName = @SortColumn
SET @Order = @SortColumn
SET @Operator = '>='
END
DECLARE @type varchar(50)
DECLARE @prec int
SELECT @type=t.name, @prec=c.prec
FROM sysobjects o
JOIN syscolumns c on o.id=c.id
JOIN systypes t on c.xusertype=t.xusertype
WHERE o.name = @SortTable AND c.name = @SortName
IF CHARINDEX('char', @type) > 0
SET @type = @type + '(' + CAST(@prec AS varchar) + ')'
DECLARE @TopRows INT
SET @TopRows = @PageSize * @CurrentPage + 1
print @TopRows
print @Operator
EXEC('
DECLARE @SortColumnBegin ' + @type + '
SET ROWCOUNT ' + @TopRows + '
SELECT @SortColumnBegin=' + @SortColumn + ' FROM ' + @TableNames + ' ' + @Filter + ' ' + @Group + ' ORDER
BY ' + @Order + '
SET ROWCOUNT ' + @PageSize + '
SELECT ' + @Fields + ' FROM ' + @TableNames + ' ' + @Filter + ' AND ' + @SortColumn + '' + @Operator +
'@SortColumnBegin ' + @Group + ' ORDER BY ' + @Order + '
')
END
GO
--调用例子:
--1.单表/单排序
EXEC usp_PagingLarge 'bigtable','d_id','d_id,d_title,d_content,d_time',20,1,'','','d_id desc'
--2.单表/多排序
EXEC usp_PagingLarge 'bigtable','d_id','*',20,0,'','','d_time asc,d_id desc'
--3.多表/单排序
EXEC usp_PagingLarge 'bigtable left join bigtable_author on bigtable.d_id=bigtable_author.BigTable_id',
'bigtable.d_id', 'bigtable.d_id,bigtable.d_title,bigtable.d_content,bigtable.d_time,bigtable_author.d_author', 20,
0, '', '', 'bigtable.d_id asc'
--4.多表/多排序
EXEC usp_PagingLarge 'bigtable left join bigtable_author on bigtable.d_id=bigtable_author.BigTable_id',
'bigtable.d_id', 'bigtable.d_id,bigtable.d_title,bigtable.d_content,bigtable.d_time,bigtable_author.d_author', 20,
0, '', '', 'bigtable.d_time asc,bigtable.d_id desc'
-------------------
调用例子
using System;
using System.Configuration;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace AspNetTest.Common
{
/// <summary>
/// Paging_Large 的摘要说明。
/// </summary>
public class Paging_Large : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DataGrid DataGrid1;
private const string TableNames = "bigtable";
private const string PrimaryKey = "d_id";
private string Fields = "d_id,d_title,d_content,d_time";
private int PageSize = 20;
private int CurrentPage = 0;
private string Filter = "";
private string Group = "";
protected System.Web.UI.HtmlControls.HtmlGenericControl FONT1;
private string Order = "d_id desc";
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
DataBind();
}
// 在此处放置用户代码以初始化页面
}
private void DataBind()
{
string connectionString = ConfigurationSettings.AppSettings["ConnectionString1"];
//Response.Write(connectionString);
//Response.End();
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
// "'" + TableNames + "','" + PrimaryKey + "','" + Fields + "'," + PageSize + "," +
CurrentPage + ",'" + Filter + "','" + Group + "','" + Order + "'";
cmd.CommandText = "usp_PagingLarge";
cmd.Parameters.Add(new SqlParameter("@TableNames", SqlDbType.VarChar, 200));
cmd.Parameters.Add(new SqlParameter("@PrimaryKey", SqlDbType.VarChar, 100));
cmd.Parameters.Add(new SqlParameter("@Fields", SqlDbType.VarChar, 200));
cmd.Parameters.Add(new SqlParameter("@PageSize", SqlDbType.Int, 4));
cmd.Parameters.Add(new SqlParameter("@CurrentPage", SqlDbType.Int, 4));
cmd.Parameters.Add(new SqlParameter("@Filter", SqlDbType.VarChar, 200));
cmd.Parameters.Add(new SqlParameter("@Group", SqlDbType.VarChar, 200));
cmd.Parameters.Add(new SqlParameter("@Order", SqlDbType.VarChar, 200));
cmd.Parameters["@TableNames"].Value = TableNames;
cmd.Parameters["@PrimaryKey"].Value = PrimaryKey;
cmd.Parameters["@Fields"].Value = Fields;
cmd.Parameters["@PageSize"].Value = PageSize;
cmd.Parameters["@CurrentPage"].Value = CurrentPage;
cmd.Parameters["@Filter"].Value = Filter;
cmd.Parameters["@Group"].Value = Group;
cmd.Parameters["@Order"].Value = Order;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds, "Article");
DataGrid1.DataSource = ds.Tables["Article"].DefaultView;
cmd.Connection.Open();
cmd = new SqlCommand("select count(d_id) from bigtable", conn);
int totalCount = (int)cmd.ExecuteScalar();
DataGrid1.VirtualItemCount = totalCount;
DataGrid1.DataBind();
conn.Close();
}
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.DataGrid1.PageIndexChanged += new
System.Web.UI.WebControls.DataGridPageChangedEventHandler(this.DataGrid1_PageIndexChanged);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void DataGrid1_PageIndexChanged(object source,
System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
{
DataGrid1.CurrentPageIndex = e.NewPageIndex;
CurrentPage = DataGrid1.CurrentPageIndex;
DataBind();
}
}
}