`
k_lb
  • 浏览: 798377 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论
  • kitleer: 据我所知,国内有款ETL调度监控工具TaskCTL,支持ket ...
    kettle调度

MS SQL Server 分页存储过程

 
阅读更多

以前经常被人家问 SQL server 如何实现分页?当一张表里面有数十万条或者更多的数据时,该怎么办?如果数据库是 SQL Server 2000,我会回答:TOP,使用 TOP 嵌套查询(或者临时表),如果是 SQL Server 2005/2008,我会回答:使用 WITH,ROW_NUMBER 和 OVER。

SQL Top

SQL Top,返回结果集中的前 N 条记录。下面的例子是返回订单量最多的前十位客户的信息。另外 TOP 关键字还可以根据百分比来返回结果,但是这里不作讨论。


SELECT TOP 10 * FROM Customers -- 这是一个最简单的例子

--下面是返回订单量最大的 10 位客户的信息
SELECT TOP 10 Customers.CustomerID, Customers.CompanyName, COUNT(*) OrderCount
FROM Customers INNER JOIN Orders ON Orders.CustomerID = Customers.CustomerID
GROUP BY Customers.CustomerID, Customers.CompanyName
ORDER BY OrderCount DESC

这种方法很容易就得到了前 10 条记录,但是如果你想得到第 11 到 20 条数据的时候,又该怎么办呢?答案是:临时表。


-- 取出前 30 条数据到临时表 #TEMP 中
SELECT TOP 30 * INTO
#TEMP
FROM Customers
ORDER BY CompanyName ASC

-- 再从临时表中取出前 10 条数据到另外一个临时表 #TEMP2 中
SELECT TOP 10 *
INTO #TEMP2
FROM #Temp
ORDER BY CompanyName DESC

-- 最后从 #TEMP2 中得到想要的数据
SELECT * FROM #TEMP2

使用这种方法,如果仅仅是想得到前几页内容的时候,还算方便,但是如果用户想要一页一页连续不断得到数据的话,这种方法效率就太低了。

WITH,ROW_NUMBER 和 OVER

这是 SQL Server 2005 中新增的方法。下面的这个例子是返回结果集中的第 20 到 29 条记录。


WITH Cust AS
    ( SELECT CustomerID, CompanyName,
    ROW_NUMBER() OVER (ORDER BY CompanyName) AS RowNumber
    FROM Customers )
SELECT *
FROM Cust
WHERE RowNumber BETWEEN 20 AND 30

SQL Server 2005 中的 WITH 关键字是为结果集指定一个临时名称,类似旧版本 SQL Server 中的临时表的概念。但是,这里最起作用的是 ROW_NUMBER 和 OVER 关键字,它们为每一条记录指定了一个行号。这种方法对于数据量大的表,查询速度非常快,在超过 250000 条记录的表上测试,表现仍然良好。

集成到存储过程中

为了以后使用方便,何不把它们集成到一个存储过程中呢?而且这个存储过程中,要可以灵活的自定义分页大小 @PageSize,和页数 @PageNumber,以便用户可以想看哪页就看哪页。


CREATE PROC GetCustomersByPage

--页大小,第几页
@PageSize INT,
@PageNumber INT 

AS 

DECLARE @RowStart INT
DECLARE @RowEnd INT

IF @PageNumber > 0
BEGIN 

SET @PageNumber = @PageNumber -1 

SET @RowStart = @PageSize * @PageNumber + 1
SET @RowEnd = @RowStart + @PageSize - 1

WITH Cust AS
     ( SELECT CustomerID, CompanyName,
       ROW_NUMBER() OVER (ORDER BY CompanyName) AS RowNumber
       FROM Customers ) 

SELECT *
FROM Cust
WHERE RowNumber >= @RowStart AND RowNumber <= @RowEnd

END


此存储过程有两个参数,@PageSize 和 @PageNumber,使用方法如下:


EXEC GetCustomersByPage 10, 1

自己修改后存储过程


USE [UILogDB]
GO
/****** Object:  StoredProcedure [dbo].[Usp_Pagination]    Script Date: 11/09/2011 09:22:36 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<jianxiong>
-- Create date: <2011-10-27>
-- Description:	<Pagination>
-- =============================================
CREATE PROCEDURE [dbo].[Usp_Pagination]
	-- Add the parameters for the stored procedure here
	@table varchar(200),	--表名
	@field varchar(max),	--字段名
	@orderby varchar(200),	--排序字段
	@PageNumber int,		--页数
	@PageSize int			--页面中行数

AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

    -- Insert statements for procedure here
	declare @RowStart int
	declare @RowEnd int
	declare @sql varchar(max)
	
	if @field=''
	set @field='*'
	
	if @orderby=''
	SELECT top 1 @orderby=syscolumns.name FROM syscolumns, systypes WHERE syscolumns.xusertype = systypes.xusertype AND syscolumns.id = object_id(''+@table+'')

	if @PageNumber=''
	set @PageNumber='0'
	
	if @PageSize=''
	set @PageSize='5'

	
	IF @PageNumber > 0  
	  
	SET @PageNumber = @PageNumber -1   
	  
	SET @RowStart = @PageSize * @PageNumber + 1  
	SET @RowEnd = @RowStart + @PageSize - 1 



	set @sql=
		('
			with temptable as 
			( select row_number() over(order by '+@orderby+') as id,'+@field+' from '+@table+' )

			select * from temptable
			where id >= '+convert(varchar(15),@RowStart)+' and id<= '+convert(varchar(15),@RowEnd)+'
			
		')

	exec (@sql)
	
END



分享到:
评论

相关推荐

    标准SQLServer分页存储过程

    微软C#.net中的宠物商店的例子 中的标准的分页存储过程

    sql的存储过程-简单分页

    很好的通过存储过程实现分页的技术,很好的通过存储过程实现分页的技术,很好的通过存储过程实现分页的技术

    MS SQLSERVER通用存储过程分页

    近在面试的时候,遇到个奇葩的秃顶老头面试官。  问:写过存储过程分页吗?...只在SQLSERVER2008上测试过,不过我想,2000以上版本应该都会支持的吧。  废话到此,上代码。 if (object_id('Pro

    SQL_Page.rar_SqlPage_page_分页_分页存储

    MS SQL Server的两个分页存储过程,一个是百万级数据分页的,一个是普通的!

    分页存储过程(二)在sqlserver中返回更加准确的分页结果

    分页存储过程(二)在MS SQL Server中返回更加准确的分页结果

    分页存储过程(三)在sqlserver中打造更加准确的分页结果

    昨天的那篇分页存储过程(二)在MS SQL Server中返回更加准确的分页结果 中使用了游标,有很多热心的朋友参与讨论,感谢大家的参与。

    FluentData微型ORM v2.3.0源码2012813

    支持存储过程。 支持分页。 查询自动映射或自定义映射到自己的实体类型(如产品类型)或动态类型(NET 4.0新)。 安全,使用索引或命名参数,以防止SQL注入。 强大的性能。 可以对任何现有的业务对象和业务层不需要...

    XML DB Query 简体中文版

    可以访问MS-SQL Server、Oracle及Access数据库,对于MS-SQL Server及Oracle可以一次执行多条SQL语句及存储过程 ?●?提供一个命令窗口,可以执行全部或选中的语句,可以将这些SQL语句保存到查询文件或从查询文件中...

    sql2005全文检索.doc

     第三步,开发存储过程并把结果集分页,以供前台页面调用返回查询的结果。  1) 建立找资本全文检索储存过程USP_CaptialInfo_FullIndex。 /* 找资本全文索引开发过程  */ CREATE PROCEDURE USP_CaptialInfo_Full...

    asp.net知识库

    可按任意字段排序的分页存储过程(不用临时表的方法,不看全文会后悔) 常用sql存储过程集锦 存储过程中实现类似split功能(charindex) 通过查询系统表得到纵向的表结构 将数据库表中的数据生成Insert脚本的存储过程!!! ...

    搜易站内搜索引擎 v4.8.4.zip

    2,多数据库支持:目前支持应用最广泛的MS SQL SERVER 2000/2005,MySQL数据库,在后台点点鼠标即可完成数据库数据汇入索引库的匹配; 3,毫秒级的速度:基于倒排索引全文索引技术核心,实现索引分块存储千万级数据...

    ASP3《高级编程》(第一部分)

    9.2.3 存储过程 276 9.3 优化 289 9.3.1 常用的ADO技巧 289 9.3.2 对象变量 289 9.3.3 高速缓存大小 290 9.3.4 数据库设计 290 9.3.5 数据高速缓存 291 9.4 数据整形 293 9.4.1 使用数据整形 294 9.4.2 ...

    ASP3《高级编程》(第二部分)

    9.2.3 存储过程 276 9.3 优化 289 9.3.1 常用的ADO技巧 289 9.3.2 对象变量 289 9.3.3 高速缓存大小 290 9.3.4 数据库设计 290 9.3.5 数据高速缓存 291 9.4 数据整形 293 9.4.1 使用数据整形 294 9.4.2 ...

    JAVA上百实例源码以及开源项目

    第一步:运行ServerData.java 启动服务器,然后服务器处于等待状态 第二步:运行LoginData.java 启动(客户端)登陆界面 输入用户名 ip为本机localhost 第三步:在登陆后的界面文本框输入文本,然后发送 可以同时启动...

    JAVA上百实例源码以及开源项目源代码

    在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天...

Global site tag (gtag.js) - Google Analytics