日期:2014-05-19  浏览次数:20475 次

讨论:Sql server 中快速的分页查询语句
有千万条记录的表
每次返回的记录数也在几十万,上万页
假定就在一张表中,使用一个语句(select)查询出某页

SELECT   TOP   50   xxx   from  
(select   top   total-(page-1)*50   xxx   from   theTable   where   ...   order   by   xxx   desc)tmp   order   by   xxx

如上为一种查询方法,请赐教各种查询语句


------解决方案--------------------
SELECT * FROM (
SELECT TOP 50* FROM (
SELECT TOP 50*(Page+1) * FROM Table
ORDER BY PrimaryKey ASC
) TableA ORDER BY PrimaryKey DESC
) TableB ORDER BY PrimaryKey ASC



------解决方案--------------------
SELECT TOP 50* FROM Table
WHERE PrimaryKey NOT IN (
SELECT TOP 50*Page PrimaryKey FROM Table
ORDER BY PrimaryKey ASC
) ORDER BY PrimaryKey ASC

------解决方案--------------------
Page是变量?

需要用动态SQL语句。


------解决方案--------------------

动态sql语句基本语法
1 :普通SQL语句可以用Exec执行

eg: Select * from tableName
Exec( 'select * from tableName ')
Exec sp_executesql N 'select * from tableName ' -- 请注意字符串前一定要加N

2:字段名,表名,数据库名之类作为变量时,必须用动态SQL

eg:
declare @fname varchar(20)
set @fname = 'FiledName '
Select @fname from tableName -- 错误,不会提示错误,但结果为固定值FiledName,并非所要。
Exec( 'select ' + @fname + ' from tableName ') -- 请注意 加号前后的 单引号的边上加空格

当然将字符串改成变量的形式也可
declare @fname varchar(20)
set @fname = 'FiledName ' --设置字段名

declare @s varchar(1000)
set @s = 'select ' + @fname + ' from tableName '
Exec(@s) -- 成功
exec sp_executesql @s -- 此句会报错


declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000)
set @s = 'select ' + @fname + ' from tableName '
Exec(@s) -- 成功
exec sp_executesql @s -- 此句正确

3. 输出参数
declare @num int,
@sqls nvarchar(4000)
set @sqls= 'select count(*) from tableName '
exec(@sqls)
--如何将exec执行结果放入变量中?

declare @num int,
@sqls nvarchar(4000)
set @sqls= 'select @a=count(*) from tableName '
exec sp_executesql @sqls,N '@a int output ',@num output
select @num


------解决方案--------------------
用邹老大的效率不错:
首先判断唯一标识\主键,没有时通过临时表实现:
/*--用存储过程实现的分页程序

显示指定表、视图、查询结果的第X页
对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法
如果视图或查询结果中有主键,不推荐此方法

--邹建 2003.09(引用请保留此信息)--*/

/*--调用示例
exec p_show '地区资料 '

exec p_show '地区资料 ',5,3, '地区编号,地区名称,助记码 ', '地区编号 '
--*/

if exists (select * from dbo.sysobjects where id = object_id(N '[dbo].[p_show] ') and OBJECTPROPERTY(id, N 'IsProcedure ') = 1)
drop procedure [dbo].[p_show]
GO

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