--方法1: --适用于 SQL Server 2000/2005 SELECT TOP 页大小 * FROM table1 WHERE id NOT IN ( SELECT TOP 页大小*(页数-1) id FROM table1 ORDER BY id ) ORDER BY id --方法2: --适用于 SQL Server 2000/2005 SELECT TOP 页大小 * FROM table1 WHERE id > ( SELECT ISNULL(MAX(id),0) FROM ( SELECT TOP 页大小*(页数-1) id FROM table1 ORDER BY id ) A ) ORDER BY id --方法3: --适用于 SQL Server 2005 SELECT TOP 页大小 * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1 ) A WHERE RowNumber > 页大小*(页数-1) --方法四 适用于 SQL Server 2005 DECLARE @pagenum AS INT, @pagesize AS INT SET @pagenum = 2 SET @pagesize = 3 SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY newsid DESC) AS rownum, newsid, topic, ntime, hits FROM news) AS D WHERE rownum BETWEEN (@pagenum-1)*@pagesize+1 AND @pagenum*@pagesize ORDER BY newsid DESC
SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO --名称:分页存储过程 --使用示例 EXEC sp_PageIndex '*',' FROM StuSources ',2,10 --注意 --目前还没有对输入的参数进行严格的验证 --默认为输入都是合法有效的ALTER PROC sp_PageIndex @sqlSelect varchar(800) --SELECT 后面 FROM 前面 的 字段 不用包含SELECT ,@sqlFrom varchar(800) --FROM 后面 的 字段 包含FROM ,@countPerPage int -- 每页数据行数 ,@toPage int --要转到的页码ASBEGIN -- 根据每页数据行数 和 要转到的页码 得到 数据起止点 Declare @start int Declare @end intset @end = @countPerPage * @toPage set @start = @countPerPage * (@toPage - 1) + 1 -- 临时表名称 可随机命名 Declare @tmpTable varchar(10) SET @tmpTable ='#tmp'Declare @sqlStr varchar(800) -- 创建数据源到临时表 SELECT @sqlStr = 'SELECT Identity(int,1,1) AS RowIndex,' SELECT @sqlStr = @sqlStr + rtrim(@sqlSelect) + ' INTO '+ @tmpTable SELECT @sqlStr = @sqlStr + rtrim(@sqlFrom) -- 查询临时表 得到所需要的数据 SELECT @sqlStr = @sqlStr + ' '+'SELECT '+ rtrim(@sqlSelect) +' FROM ' + @tmpTable SELECT @sqlStr = @sqlStr + ' WHERE RowIndex BETWEEN ' + Convert(char,@start) + " AND " + Convert(char,@end) -- 删除临时表 SELECT @sqlStr = @sqlStr + ' '+'DROP TABLE '+@tmpTable EXEC (@sqlStr) END GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
优点:
1.由于应用程序随着时间推移会不断更改,增删功能,T-SQL过程代码会变得更复杂,StoredProcedure为封装此代码提供了一个替换位置。2.执行计划(存储过程在首次运行时将被编译,这将产生一个执行计划-- 实际上是 Microsoft SQL Server为在存储过程中获取由 T-SQL 指定的结果而必须采取的步骤的记录。)缓存改善性能。
........但sql server新版本,执行计划已针对所有 T-SQL 批处理进行了缓存,而不管它们是否在存储过程中,所以没比较优势了。3.存储过程可以用于降低网络流量,存储过程代码直接存储于数据库中,所以不会产生大量T-sql语句的代码流量。4.使用存储过程使您能够增强对执行计划的重复使用,由此可以通过使用远程过程调用 (RPC) 处理服务器上的存储过程而提高性能。RPC 封装参数和调用服务器端过程的方式使引擎能够轻松地找到匹配的执行计划,并只需插入更新的参数值。5.可维护性高,更新存储过程通常比更改、测试以及重新部署程序集需要较少的时间和精力。6.代码精简一致,一个存储过程可以用于应用程序代码的不同位置。7.更好的版本控制,通过使用 Microsoft Visual SourceSafe 或某个其他源代码控制工具,您可以轻松地恢复到或引用旧版本的存储过程。8.增强安全性:
a、通过向用户授予对存储过程(而不是基于表)的访问权限,它们可以提供对特定数据的访问;
b、提高代码安全,防止 SQL注入(但未彻底解决,例如,将数据操作语言--DML,附加到输入参数);
c、SqlParameter 类指定存储过程参数的数据类型,作为深层次防御性策略的一部分,可以验证用户提供的值类型(但也不是万无一失,还是应该传递至数据库前得到附加验证)。
比如现在有个userinfo表,里面全部是用户信息。现在要查出第十页的用户的信息呢
userid主键,10条一页。是从第一页直接输入10跳到第十页。
是不是会把前100条记录查出来倒序排列取前十条呢,这样的话如果记录多,跳的页很大的话,性能一定很低咯。
只是个人想法呵呵,到底该怎么写呢?请高手赐教。
--适用于 SQL Server 2000/2005
SELECT TOP 页大小 *
FROM table1
WHERE id NOT IN
(
SELECT TOP 页大小*(页数-1) id FROM table1 ORDER BY id
)
ORDER BY id
--方法2:
--适用于 SQL Server 2000/2005
SELECT TOP 页大小 *
FROM table1
WHERE id >
(
SELECT ISNULL(MAX(id),0)
FROM
(
SELECT TOP 页大小*(页数-1) id FROM table1 ORDER BY id
) A
)
ORDER BY id
--方法3:
--适用于 SQL Server 2005
SELECT TOP 页大小 *
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNumber,* FROM table1
) A
WHERE RowNumber > 页大小*(页数-1)
--方法四 适用于 SQL Server 2005
DECLARE @pagenum AS INT, @pagesize AS INT
SET @pagenum = 2
SET @pagesize = 3
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY newsid DESC) AS rownum,
newsid, topic, ntime, hits
FROM news) AS D
WHERE rownum BETWEEN (@pagenum-1)*@pagesize+1 AND @pagenum*@pagesize
ORDER BY newsid DESC
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
--名称:分页存储过程
--使用示例 EXEC sp_PageIndex '*',' FROM StuSources ',2,10
--注意
--目前还没有对输入的参数进行严格的验证
--默认为输入都是合法有效的ALTER PROC sp_PageIndex
@sqlSelect varchar(800) --SELECT 后面 FROM 前面 的 字段 不用包含SELECT
,@sqlFrom varchar(800) --FROM 后面 的 字段 包含FROM
,@countPerPage int -- 每页数据行数
,@toPage int --要转到的页码ASBEGIN
-- 根据每页数据行数 和 要转到的页码 得到 数据起止点
Declare @start int
Declare @end intset @end = @countPerPage * @toPage
set @start = @countPerPage * (@toPage - 1) + 1
-- 临时表名称 可随机命名
Declare @tmpTable varchar(10)
SET @tmpTable ='#tmp'Declare @sqlStr varchar(800)
-- 创建数据源到临时表
SELECT @sqlStr = 'SELECT Identity(int,1,1) AS RowIndex,'
SELECT @sqlStr = @sqlStr + rtrim(@sqlSelect) + ' INTO '+ @tmpTable
SELECT @sqlStr = @sqlStr + rtrim(@sqlFrom)
-- 查询临时表 得到所需要的数据
SELECT @sqlStr = @sqlStr + ' '+'SELECT '+ rtrim(@sqlSelect) +' FROM ' + @tmpTable
SELECT @sqlStr = @sqlStr + ' WHERE RowIndex BETWEEN ' + Convert(char,@start) + " AND " + Convert(char,@end)
-- 删除临时表
SELECT @sqlStr = @sqlStr + ' '+'DROP TABLE '+@tmpTable
EXEC (@sqlStr)
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
wufeng4552大侠的前几种方法好像都是要把前面的数据全部查出来,在过滤剩下最后十条。这样的效率是不是有点跟不上呀。各位认为呢。有没有办法能让效率变到最高呢?可以直接一点的查询目标记录...
如果表里已经有你想要的排序号,比如id,
就能直接写:select * from tb where id between 100 and 110;
如果没有现成的,则必须先按指定规则进行排序,再根据排序来选择。