您的位置:首页 > 数据库

一个通用的sql 分页查询语句

2009-12-23 14:23 645 查看
代码

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

/*
===================================================================
名称:sp_GetRecordFromPage
功能:千万级记录通用查询分页功能
输入参数:
@tblName varchar(1000), -- 表名
@SelectFieldName varchar(4000), -- 要显示的字段名(不要加select)字段名用,隔开
@strWhere varchar(4000), -- 查询条件(注意: 不要加 where)
@OrderFieldName varchar(255), -- 排序索引字段名
@PageSize int , -- 页大小
@PageIndex int = 1, -- 页码
@iRowCount int output, -- 返回记录总数
@OrderType bit = 0 -- 设置排序类型, 非 0 值则降序
返回:此条件的记录总数
适用的表:任意表
影响的表:任意表
日期:2004-12-01 14:52
作者:xiemail

日期:2009-9-11 14:52
作者:ykaiyong 使用ROW_NUMBER,解决排序字段重复值引起的bug
备注:
===================================================================
*/
ALTER PROCEDURE [dbo].[sp_GetRecordFromPage]
(
@tblName varchar(1000), -- 表名
@SelectFieldName varchar(4000), -- 要显示的字段名(不要加select)字段名用,隔开
@strWhere varchar(4000), -- 查询条件(注意: 不要加 where)
@OrderFieldName varchar(255), -- 排序索引字段名
@PageSize int , -- 页大小
@PageIndex int = 1, -- 页码
@iRowCount int output, -- 返回记录总数
@OrderType bit = 0 -- 设置排序类型, 非 0 值则降序
)
AS

Declare @strSQL varchar(4000) -- 主语句
Declare @strTmp varchar(4000) -- 临时变量
Declare @strOrder varchar(400) -- 排序类型
Declare @strRowCount nvarchar(4000) -- 用于查询记录总数的语句

Set @OrderFieldName = ltrim(rtrim(@OrderFieldName))

If @OrderType != 0--如果排序类型不为0,则降序
Begin
IF CHARINDEX('.',@OrderFieldName)>0
BEGIN
PRINT CHARINDEX('.',@OrderFieldName)
Set @strTmp = ' ORDER BY ' +substring(@OrderFieldName,CHARINDEX('.',@OrderFieldName)+1,LEN(@OrderFieldName)-CHARINDEX('.',@OrderFieldName)) +' DESC'
END
ELSE
BEGIN
Set @strTmp = ' ORDER BY ' +@OrderFieldName +' DESC'
END
Set @strOrder = ' ORDER BY ' + @OrderFieldName +' DESC'
End
Else
Begin
IF CHARINDEX('.',@OrderFieldName)>0
BEGIN
PRINT CHARINDEX('.',@OrderFieldName)
Set @strTmp = ' ORDER BY ' +substring(@OrderFieldName,CHARINDEX('.',@OrderFieldName)+1,LEN(@OrderFieldName)-CHARINDEX('.',@OrderFieldName)) +' ASC'
END
ELSE
BEGIN
Set @strTmp = ' ORDER BY ' +@OrderFieldName +' ASC'
END

Set @strOrder = ' ORDER BY ' + @OrderFieldName +' ASC'
End
/*----例句如下,只支持sql server 2005 --------
SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY addtime DESC) AS rownum,*
FROM dbo.Resources where rid>7) AS D
WHERE rownum BETWEEN 20 and 80 order by addtime DESC (@PageIndex-1)*@PageSize+1 AND @PageIndex*@PageSize
order by addtime DESC
-----ORDER BY id DESC
*/
IF CHARINDEX(',',@tblName) >0
BEGIN
PRINT '多表查询'
If @strWhere != ''
begin
--若条件查询语句不为空
Set @strSQL = 'Select * from '
+ '(SELECT ROW_NUMBER() OVER('+@strOrder+') AS rownum,'+ @SelectFieldName +' FROM '+ @tblName + ' where ' + @strWhere
+ ' ) as D WHERE rownum BETWEEN ' + Convert(varchar(50),(@PageIndex-1)*@PageSize+1) + ' AND ' + Convert(varchar(50),@PageIndex*@PageSize) + @strTmp
end
Else
begin
Set @strSQL = 'Select ' + @SelectFieldName + ' from '
+ '(SELECT ROW_NUMBER() OVER('+@strOrder+') AS rownum,* FROM '+ @tblName + ' '
+ ' ) as D WHERE rownum BETWEEN ' + Convert(varchar(50),(@PageIndex-1)*@PageSize+1) + ' AND ' + Convert(varchar(50),@PageIndex*@PageSize) + @strTmp
end
END
ELSE
BEGIN
If @strWhere != ''
begin
--若条件查询语句不为空
Set @strSQL = 'Select ' + @SelectFieldName + ' from '
+ '(SELECT ROW_NUMBER() OVER('+@strOrder+') AS rownum,* FROM '+ @tblName + ' where ' + @strWhere
+ ' ) as D WHERE rownum BETWEEN ' + Convert(varchar(50),(@PageIndex-1)*@PageSize+1) + ' AND ' + Convert(varchar(50),@PageIndex*@PageSize) + @strTmp
end
Else
begin
Set @strSQL = 'Select ' + @SelectFieldName + ' from '
+ '(SELECT ROW_NUMBER() OVER('+@strOrder+') AS rownum,* FROM '+ @tblName + ' '
+ ' ) as D WHERE rownum BETWEEN ' + Convert(varchar(50),(@PageIndex-1)*@PageSize+1) + ' AND ' + Convert(varchar(50),@PageIndex*@PageSize) + @strTmp
end
END
Print (@strSQL)
Exec(@strSQL)

If @strWhere != ''
Set @strRowCount = 'Select @iRowCount = count(*) from ' + @tblName+' where ' + @strWhere
Else
Set @strRowCount = 'Select @iRowCount = count(*) from ' + @tblName

Exec sp_executesql @strRowCount , N'@iRowCount int out' , @iRowCount out

分页查询的中心思想就是先重写行号,然后根据行号读取pagesize个数据

Exec sp_executesql 这个的作用是执行'ntext/nchar/nvarchar'类型的语句

例如:

declare @g nvarchar(500)
set @g='select 1 as a'
Execute sp_executesql @g
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: