2分法-通用存储过程分页(top max模式)版本(性能相对之前的not in版本极大提高)
--
/*-----存储过程 分页处理 SW 2005-03-28创建 -------*/
--
/*----- 对数据进行了2分处理使查询前半部分数据与查询后半部分数据性能相同 -------*/
--
/*-----存储过程 分页处理 2005-04-21修改 添加Distinct查询功能-------*/
--
/*-----存储过程 分页处理 2005-05-18修改 多字段排序规则问题-------*/
--
/*-----存储过程 分页处理 2005-06-15修改 多字段排序修改-------*/
--
/*-----存储过程 分页处理 2005-12-13修改 修改数据分页方式为top max模式 性能有极大提高-------*/
--
/*-----缺点:相对之前的not in版本主键只能是整型字段,如主键为GUID类型请使用not in 模式的版本-------*/
CREATE
PROCEDURE
dbo.proc_ListPageInt
(
@tblName
nvarchar
(
200
),
--
--要显示的表或多个表的连接
@fldName
nvarchar
(
500
)
=
'
*
'
,
--
--要显示的字段列表
@pageSize
int
=
10
,
--
--每页显示的记录个数
@page
int
=
1
,
--
--要显示那一页的记录
@pageCount
int
=
1
output,
--
--查询结果分页后的总页数
@Counts
int
=
1
output,
--
--查询到的记录数
@fldSort
nvarchar
(
200
)
=
null
,
--
--排序字段列表或条件
@Sort
bit
=
0
,
--
--排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记)--程序传参如:' SortA Asc,SortB Desc,SortC ')
@strCondition
nvarchar
(
1000
)
=
null
,
--
--查询条件,不需where
@ID
nvarchar
(
150
),
--
--主表的主键
@Dist
bit
=
0
--
--是否添加查询字段的 DISTINCT 默认0不添加/1添加
)
AS
SET
NOCOUNT
ON
Declare
@sqlTmp
nvarchar
(
1000
)
--
--存放动态生成的SQL语句
Declare
@strTmp
nvarchar
(
1000
)
--
--存放取得查询结果总数的查询语句
Declare
@strID
nvarchar
(
1000
)
--
--存放取得查询开头或结尾ID的查询语句
Declare
@strSortType
nvarchar
(
10
)
--
--数据排序规则A
Declare
@strFSortType
nvarchar
(
10
)
--
--数据排序规则B
Declare
@SqlSelect
nvarchar
(
50
)
--
--对含有DISTINCT的查询进行SQL构造
Declare
@SqlCounts
nvarchar
(
50
)
--
--对含有DISTINCT的总数查询进行SQL构造
if
@Dist
=
0
begin
set
@SqlSelect
=
'
select
'
set
@SqlCounts
=
'
Count(*)
'
end
else
begin
set
@SqlSelect
=
'
select distinct
'
set
@SqlCounts
=
'
Count(DISTINCT
'
+
@ID
+
'
)
'
end
if
@Sort
=
0
begin
set
@strFSortType
=
'
ASC
'
set
@strSortType
=
'
DESC
'
end
else
begin
set
@strFSortType
=
'
DESC
'
set
@strSortType
=
'
ASC
'
end
--
------生成查询语句--------
--
此处@strTmp为取得查询结果数量的语句
if
@strCondition
is
null
or
@strCondition
=
''
--
没有设置显示条件
begin
set
@sqlTmp
=
@fldName
+
'
From
'
+
@tblName
set
@strTmp
=
@SqlSelect
+
'
@Counts=
'
+
@SqlCounts
+
'
FROM
'
+
@tblName
set
@strID
=
'
From
'
+
@tblName
end
else
begin
set
@sqlTmp
=
+
@fldName
+
'
From
'
+
@tblName
+
'
where (1>0)
'
+
@strCondition
set
@strTmp
=
@SqlSelect
+
'
@Counts=
'
+
@SqlCounts
+
'
FROM
'
+
@tblName
+
'
where (1>0)
'
+
@strCondition
set
@strID
=
'
From
'
+
@tblName
+
'
where (1>0)
'
+
@strCondition
end
--
--取得查询结果总数量-----
exec
sp_executesql
@strTmp
,N
'
@Counts int out
'
,
@Counts
out
declare
@tmpCounts
int
if
@Counts
=
0
set
@tmpCounts
=
1
else
set
@tmpCounts
=
@Counts
--
取得分页总数
set
@pageCount
=
(
@tmpCounts
+
@pageSize
-
1
)
/
@pageSize
/**/
/**当前页大于总页数 取最后一页**/
if
@page
>
@pageCount
set
@page
=
@pageCount
--
/*-----数据分页2分处理-------*/
declare
@pageIndex
int
--
总数/页大小
declare
@lastcount
int
--
总数%页大小
set
@pageIndex
=
@tmpCounts
/
@pageSize
set
@lastcount
=
@tmpCounts
%
@pageSize
if
@lastcount
>
0
set
@pageIndex
=
@pageIndex
+
1
else
set
@lastcount
=
@pagesize
--
//***显示分页
if
@strCondition
is
null
or
@strCondition
=
''
--
没有设置显示条件
begin
if
@pageIndex
<
2
or
@page
<=
@pageIndex
/
2
+
@pageIndex
%
2
--
前半部分数据处理
begin
if
@page
=
1
set
@strTmp
=
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
as
VARCHAR
(
4
))
+
'
'
+
@fldName
+
'
from
'
+
@tblName
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
else
begin
set
@strTmp
=
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
as
VARCHAR
(
4
))
+
'
'
+
@fldName
+
'
from
'
+
@tblName
+
'
where
'
+
@ID
+
'
<(select min(
'
+
@ID
+
'
) from (
'
+
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
*
(
@page
-
1
)
as
Varchar
(
20
))
+
'
'
+
@ID
+
'
from
'
+
@tblName
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
+
'
) AS TBMinID)
'
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
end
end
else
begin
set
@page
=
@pageIndex
-
@page
+
1
--
后半部分数据处理
if
@page
<=
1
--
最后一页数据显示
set
@strTmp
=
@SqlSelect
+
'
* from (
'
+
@SqlSelect
+
'
top
'
+
CAST
(
@lastcount
as
VARCHAR
(
4
))
+
'
'
+
@fldName
+
'
from
'
+
@tblName
+
'
order by
'
+
@fldSort
+
'
'
+
@strSortType
+
'
) AS TempTB
'
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
else
set
@strTmp
=
@SqlSelect
+
'
* from (
'
+
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
as
VARCHAR
(
4
))
+
'
'
+
@fldName
+
'
from
'
+
@tblName
+
'
where
'
+
@ID
+
'
>(select max(
'
+
@ID
+
'
) from(
'
+
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
*
(
@page
-
2
)
+
@lastcount
as
Varchar
(
20
))
+
'
'
+
@ID
+
'
from
'
+
@tblName
+
'
order by
'
+
@fldSort
+
'
'
+
@strSortType
+
'
) AS TBMaxID)
'
+
'
order by
'
+
@fldSort
+
'
'
+
@strSortType
+
'
) AS TempTB
'
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
end
end
else
--
有查询条件
begin
if
@pageIndex
<
2
or
@page
<=
@pageIndex
/
2
+
@pageIndex
%
2
--
前半部分数据处理
begin
if
@page
=
1
set
@strTmp
=
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
as
VARCHAR
(
4
))
+
'
'
+
@fldName
+
'
from
'
+
@tblName
+
'
where 1=1
'
+
@strCondition
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
else
begin
set
@strTmp
=
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
as
VARCHAR
(
4
))
+
'
'
+
@fldName
+
'
from
'
+
@tblName
+
'
where
'
+
@ID
+
'
<(select min(
'
+
@ID
+
'
) from (
'
+
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
*
(
@page
-
1
)
as
Varchar
(
20
))
+
'
'
+
@ID
+
'
from
'
+
@tblName
+
'
where (1=1)
'
+
@strCondition
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
+
'
) AS TBMinID)
'
+
'
'
+
@strCondition
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
end
end
else
begin
set
@page
=
@pageIndex
-
@page
+
1
--
后半部分数据处理
if
@page
<=
1
--
最后一页数据显示
set
@strTmp
=
@SqlSelect
+
'
* from (
'
+
@SqlSelect
+
'
top
'
+
CAST
(
@lastcount
as
VARCHAR
(
4
))
+
'
'
+
@fldName
+
'
from
'
+
@tblName
+
'
where (1=1)
'
+
@strCondition
+
'
order by
'
+
@fldSort
+
'
'
+
@strSortType
+
'
) AS TempTB
'
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
else
set
@strTmp
=
@SqlSelect
+
'
* from (
'
+
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
as
VARCHAR
(
4
))
+
'
'
+
@fldName
+
'
from
'
+
@tblName
+
'
where
'
+
@ID
+
'
>(select max(
'
+
@ID
+
'
) from(
'
+
@SqlSelect
+
'
top
'
+
CAST
(
@pageSize
*
(
@page
-
2
)
+
@lastcount
as
Varchar
(
20
))
+
'
'
+
@ID
+
'
from
'
+
@tblName
+
'
where (1=1)
'
+
@strCondition
+
'
order by
'
+
@fldSort
+
'
'
+
@strSortType
+
'
) AS TBMaxID)
'
+
'
'
+
@strCondition
+
'
order by
'
+
@fldSort
+
'
'
+
@strSortType
+
'
) AS TempTB
'
+
'
order by
'
+
@fldSort
+
'
'
+
@strFSortType
end
end
--
----返回查询结果-----
exec
sp_executesql
@strTmp
--
print @strTmp
SET
NOCOUNT
OFF
GO
调用方法列子:
/**/
/// <summary>
/// 通用分页数据读取函数
/// 注意:在函数调用外部打开和关闭连接,以及关闭数据读取器
/// </summary>
/// <param name="comm">SqlCommand对象</param>
/// <param name="_tblName">查询的表/表联合</param>
/// <param name="_fldName">要查询的字段名</param>
/// <param name="_pageSize">每页数据大小</param>
/// <param name="_page">当前第几页</param>
/// <param name="_fldSort">排序字段</param>
/// <param name="_Sort">排序顺序0降序1升序</param>
/// <param name="_strCondition">过滤条件</param>
/// <param name="_ID">主表主键</param>
/// <param name="_dr">返回的SqlDataReader ref</param>
public
static
void
CutPageData(SqlConnection conn,
ref
SqlCommand comm,
string
_tblName,
string
_fldName,
int
_pageSize,
int
_page,
string
_fldSort,
int
_Sort,
string
_strCondition,
string
_ID,
ref
SqlDataReader _dr)
{
//注意:在函数调用外部打开和关闭连接,以及关闭数据读取器
//comm = new SqlCommand("proc_ListPage",conn);
//comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.Add("@tblName", SqlDbType.NVarChar, 200);
comm.Parameters["@tblName"].Value = _tblName;
comm.Parameters.Add("@fldName", SqlDbType.NVarChar, 500);
comm.Parameters["@fldName"].Value = _fldName;
comm.Parameters.Add("@pageSize", SqlDbType.Int);
comm.Parameters["@pageSize"].Value = _pageSize;
comm.Parameters.Add("@page", SqlDbType.Int);
comm.Parameters["@page"].Value = _page;
comm.Parameters.Add("@fldSort", SqlDbType.NVarChar, 200);
comm.Parameters["@fldSort"].Value = _fldSort;
comm.Parameters.Add("@Sort", SqlDbType.Bit);
comm.Parameters["@Sort"].Value = _Sort;
comm.Parameters.Add("@strCondition", SqlDbType.NVarChar, 1000);
comm.Parameters["@strCondition"].Value = _strCondition;
comm.Parameters.Add("@ID", SqlDbType.NVarChar, 150);
comm.Parameters["@ID"].Value = _ID;
comm.Parameters.Add("@Counts", SqlDbType.Int, 0);
comm.Parameters["@Counts"].Direction = ParameterDirection.Output;
comm.Parameters.Add("@pageCount", SqlDbType.Int, 0);
comm.Parameters["@pageCount"].Direction = ParameterDirection.Output;
_dr = comm.ExecuteReader();
}
调用例如:
CutPageData(conn, ref comm, "VOX_CDSinger", "id, cdsinger, cdsingertype, area, cdsingerreadme", 15, page, "id", 1, strFilter, "id", ref dr);
对应说明:
CutPageData(数据连接对象, ref Sqlcommand对象, "需要表或视图名称", "要查询的字段", 每页读取数据条数, 当前页, "
排序字段可多字段如(addtime desc, visitcounts注意这里最后一个字段不加desc或asc 最后一个字段对应于后面的排序规则)", 排序方式(1 desc 0 asc), where条件(这里不再添加where条件添加如:' and visitcounts>100'), 表主键, ref 返回的SqlDataReader对象);