SQL SERVER 2005 分页

select * from    
(
        select row_number() over(order by FieldA) as RowNum, *
 from  TableA   
) t
 where   t.RowNum between 10 and 20

SELECT TOP 20 * FROM (SELECT
   ROW_NUMBER() OVER (ORDER BY Namec) AS RowNumber,
   *
FROM
   dbo.mem_member) _myResults
WHERE
   RowNumber > 10000

SELECT * FROM (SELECT
   ROW_NUMBER() OVER (ORDER BY Namec) AS RowNumber,
   *
FROM
   dbo.mem_member) _myResults
WHERE
   RowNumber between 10000 and 10020

WITH OrderedResults AS

(SELECT *, ROW_NUMBER() OVER (order by Namec) as RowNumber FROM dbo.mem_member)

SELECT *

FROM OrderedResults

WHERE RowNumber between 10000 and 10020

临时表方法

1BEGIN
 2                DECLARE @PageLowerBound int
 3                DECLARE @PageUpperBound int
 4                
 5                -- Set the page bounds
 6                SET @PageLowerBound = 10000
 7                SET @PageUpperBound = 10020
 8
 9                -- Create a temp table to store the select results
10                Create Table #PageIndex
11                (
12                    [IndexId] int IDENTITY (1, 1) NOT NULL,
13                    [Id] varchar(18) 
14                )
15                
16                -- Insert into the temp table
17                declare @SQL as nvarchar(4000)
18                SET @SQL = 'INSERT INTO #PageIndex (Id)'
19                SET @SQL = @SQL + ' SELECT'
20                SET @SQL = @SQL + ' TOP ' + convert(nvarchar, @PageUpperBound)
21                SET @SQL = @SQL + ' m_id'
22                SET @SQL = @SQL + ' FROM dbo.mem_member'
23                SET @SQL = @SQL + ' ORDER BY NameC'
24                
25                -- Populate the temp table
26                exec sp_executesql @SQL
27
28                -- Return paged results
29                SELECT O.*
30                FROM
31                    dbo.mem_member O,
32                    #PageIndex PageIndex
33                WHERE
34                    PageIndex.IndexID > @PageLowerBound
35                    AND O.[m_Id] = PageIndex.[Id]
36                ORDER BY
37                    PageIndex.IndexID
38                
39drop table #PageIndex            
40                END

表变量方法和临时表差不多, 就是用的内存太多.

ROWCOUNT

1begin
 2DECLARE @first_id varchar(18), @startRow int
 3    
 4SET ROWCOUNT 10000
 5SELECT @first_id = m_id FROM mem_member ORDER BY m_id
 6
 7SET ROWCOUNT 20
 8
 9SELECT m.* 
10FROM mem_member m
11WHERE m_id >= @first_id
12ORDER BY m.m_id
13
14SET ROWCOUNT 0
15end

SQL Server存储过程设计和优化措施

 一、适合读者对象:数据库开发程序员,数据库的数据量很多,涉及到对SP(存储过程)的优化的项目开发人员,对数据库有浓厚兴趣的人。  

  二、介绍:在数据库的开发过程中,经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作。如果项目的SP较多,书写又没有一定的规范,将会影响以后的系统维护困难和大SP逻辑的难以理解,另外如果数据库的数据量大或者项目对SP的性能要求很,就会遇到优化的问题,否则速度有可能很慢,经过亲身经验,一个经过优化过的SP要比一个性能差的SP的效率甚至高几百倍。  

  三、内容:  

  1、开发人员如果用到其他库的Table或View,务必在当前库中建立View来实现跨库操作,最好不要直接使用“databse.dbo.table_name”,因为sp_depends不能显示出该SP所使用的跨库table或view,不方便校验。  

  2、开发人员在提交SP前,必须已经使用set showplan on分析过查询计划,做过自身的查询优化检查。  

  3、高程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点:   

  a)SQL的使用规范:

   i. 尽量避免大事务操作,慎用holdlock子句,提高系统并发能力。

   ii. 尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接。

   iii. 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作。

   iv. 注意where字句写法,必须考虑语句顺序,应该根据索引顺序、范围大小来确定条件子句的前后顺序,尽可能的让字段顺序与索引顺序相一致,范围从大到小。

   v. 不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

   vi. 尽量使用exists代替select count(1)来判断是否存在记录,count函数只有在统计表中所有行数时使用,而且count(1)比count(*)更有效率。

   vii. 尽量使用“>=”,不要使用“>”。

   viii. 注意一些or子句和union子句之间的替换

   ix. 注意表之间连接的数据类型,避免不同类型数据之间的连接。

   x. 注意存储过程中参数和数据类型的关系。

   xi. 注意insert、update操作的数据量,防止与其他应用冲突。如果数据量超过200个数据页面(400k),那么系统将会进行锁升级,页级锁会升级成表级锁。   

  b)索引的使用规范:

   i. 索引的创建要与应用结合考虑,建议大的OLTP表不要超过6个索引。

   ii. 尽可能的使用索引字段作为查询条件,尤其是聚簇索引,必要时可以通过index index_name来强制指定索引

   iii. 避免对大表查询时进行table scan,必要时考虑新建索引。

   iv. 在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。

   v. 要注意索引的维护,周期性重建索引,重新编译存储过程。  

  c)tempdb的使用规范:

   i. 尽量避免使用distinct、order by、group by、having、join、cumpute,因为这些语句会加重tempdb的负担。

   ii. 避免频繁创建和删除临时表,减少系统表资源的消耗。

   iii. 在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。

   iv. 如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。

    v. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定。

    vi. 慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。  
  d)合理的算法使用:   

  根据上面已提到的SQL优化技术和ASE Tuning手册中的SQL优化内容,结合实际应用,采用多种算法进行比较,以获得消耗资源最少、效率最高的方法。具体可用ASE调优命令:set statistics io on, set statistics time on , set showplan on 等。

一、前言:在经过一段时间的存储过程开发之后,写下了一些开发时候的小结和经验与大家共享,希望对大家有益,主要是针对Sybase和SQL Server数据库,但其它数据库应该有一些共性。

二、适合读者对象:数据库开发程序员,数据库的数据量很多,涉及到对SP(存储过程)的优化的项目开发人员,对数据库有浓厚兴趣的人。

三、介绍:在数据库的开发过程中,经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作。如果项目的SP较多,书写又没有一定的规范,将会影响以后的系统维护困难和大SP逻辑的难以理解,另外如果数据库的数据量大或者项目对SP的性能要求很,就会遇到优化的问题,否则速度有可能很慢,经过亲身经验,一个经过优化过的SP要比一个性能差的SP的效率甚至高几百倍。

四、    内容:

1、开发人员如果用到其他库的Table或View,务必在当前库中建立View来实现跨库操作,最好不要直接使用“databse.dbo.table_name”,因为sp_depends不能显示出该SP所使用的跨库table或view,不方便校验。

2、开发人员在提交SP前,必须已经使用set showplan on分析过查询计划,做过自身的查询优化检查。

3、高程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点:

a)    SQL的使用规范:

             i.       尽量避免大事务操作,慎用holdlock子句,提高系统并发能力。

            ii.       尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接。

           iii.       尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作。

           iv.       注意where字句写法,必须考虑语句顺序,应该根据索引顺序、范围大小来确定条件子句的前后顺序,尽可能的让字段顺序与索引顺序相一致,范围从大到小。

            v.       不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

           vi.       尽量使用exists代替select count(1)来判断是否存在记录,count函数只有在统计表中所有行数时使用,而且count(1)比count(*)更有效率。

          vii.       尽量使用“>=”,不要使用“>”。

         viii.       注意一些or子句和union子句之间的替换

           ix.       注意表之间连接的数据类型,避免不同类型数据之间的连接。

            x.       注意存储过程中参数和数据类型的关系。

           xi.       注意insert、update操作的数据量,防止与其他应用冲突。如果数据量超过200个数据页面(400k),那么系统将会进行锁升级,页级锁会升级成表级锁。

b)    索引的使用规范:

             i.       索引的创建要与应用结合考虑,建议大的OLTP表不要超过6个索引。

            ii.       尽可能的使用索引字段作为查询条件,尤其是聚簇索引,必要时可以通过index index_name来强制指定索引

           iii.       避免对大表查询时进行table scan,必要时考虑新建索引。

           iv.       在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。

            v.       要注意索引的维护,周期性重建索引,重新编译存储过程。

c)    tempdb的使用规范:

             i.       尽量避免使用distinct、order by、group by、having、join、cumpute,因为这些语句会加重tempdb的负担。

            ii.       避免频繁创建和删除临时表,减少系统表资源的消耗。

           iii.       在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。

           iv.       如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。

            v.       如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定。

           vi.       慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。

d)    合理的算法使用:

根据上面已提到的SQL优化技术和ASE Tuning手册中的SQL优化内容,结合实际应用,采用多种算法进行比较,以获得消耗资源最少、效率最高的方法。具体可用ASE调优命令:set statistics io on, set statistics time on , set showplan on 等。

ORACLE分页

1. 最好还是利用分析函数
row_number() over ( partition by col1 order by col2 )

比如想取出100-150条记录,按照tname排序

select tname,taBType from (
   select tname,tabtype,row_number() over ( order by tname ) rn from tab
)
where rn between 100 and 150;

2. 直接使用rownum 虚列
select tname,tabtype from (
   select tname,tabtype,rownum rn from tab where rownum <= 150
)
where rn >= 100;
使用序列不能基于整个记录集合进行排序,假如指定了order by子句,排序的的是选出来的记录集的排序.

------------------------------------------------------------------------
经过我的测试,在100万条数据的表中,检索数据的时候,方法2的速度要比方法1要快的.

http://www.4guysfromrolla.com/webtech/042606-1.shtml

http://www.4guysfromrolla.com/webtech/041206-1.shtml

http://www.singingeels.com/Articles/Pagination_In_SQL_Server_2005.aspx

http://blog.itpub.net/category/2879/5348

建立聚集索引要求的:“既不能绝大多数都相同,又不能只有极少数相同”的规则

何时使用聚集索引或非聚集索引

下面的表总结了何时使用聚集索引或非聚集索引(很重要)。

动作描述

使用聚集索引

使用非聚集索引

列经常被分组排序

返回某范围内的数据

不应

一个或极少不同值

不应

不应

小数目的不同值

不应

大数目的不同值

不应

频繁更新的列

不应

外键列

主键列

频繁修改索引列

不应

http://richardhan.bokee.com/1332240.html

/*
  经测试,在 14483461 条记录中查询第 100000 页,每页 10 条记录按升序和降序第一次时间均为 0.47 秒,第二次时间均为 0.43 秒,测试语法如下:
  exec GetRecordFromPage news,newsid,10,100000
  news 为 表名, newsid 为关键字段, 使用时请先对 newsid 建立索引。
*/

/*
  函数名称: GetRecordFromPage
  函数功能: 获取指定页的数据
  参数说明: @tblName      包含数据的表名
           @fldName      关键字段名
           @PageSize     每页记录数
           @PageIndex    要获取的页码
           @OrderType    排序类型, 0 - 升序, 1 - 降序
           @strWhere     查询条件 (注意: 不要加 where)
  作  者: 铁拳
  邮  箱: unjianhua_kki@sina.com">sunjianhua_kki@sina.com
  创建时间: 2004-07-04
  修改时间: 2004-07-04
*/
CREATE PROCEDURE GetRecordFromPage
    @tblName      varchar(255),       -- 表名
    @fldName      varchar(255),       -- 字段名
    @PageSize     int = 10,           -- 页尺寸
    @PageIndex    int = 1,            -- 页码
    @OrderType    bit = 0,            -- 设置排序类型, 非 0 值则降序
    @strWhere     varchar(2000) = ''  -- 查询条件 (注意: 不要加 where)
AS

declare @strSQL   varchar(6000)       -- 主语句
declare @strTmp   varchar(1000)       -- 临时变量
declare @strOrder varchar(500)        -- 排序类型

if @OrderType != 0
begin
    set @strTmp = "<(select min"
    set @strOrder = " order by [" + @fldName +"] desc"
end
else
begin
    set @strTmp = ">(select max"
    set @strOrder = " order by [" + @fldName +"] asc"
end

set @strSQL = "select top " + str(@PageSize) + " * from ["
    + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
    + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
    + @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
    + @strOrder

if @strWhere != ''
    set @strSQL = "select top " + str(@PageSize) + " * from ["
        + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
        + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
        + @fldName + "] from [" + @tblName + "] where " + @strWhere + " "
        + @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder

if @PageIndex = 1
begin
    set @strTmp = ""
    if @strWhere != ''
        set @strTmp = " where (" + @strWhere + ")"

set @strSQL = "select top " + str(@PageSize) + " * from ["
        + @tblName + "]" + @strTmp + " " + @strOrder
end

exec (@strSQL)

GO

改一下,看看这样是不是更好一点?

/*

函数名称: GetRecordFromPage

函数功能: 获取指定页的数据

参数说明:   @tblName        包含数据的表名

@fldName        关键字段名

@PageSize      每页记录数

@PageIndex    要获取的页码

@IsCount         是否要取得记录数

@OrderType    排序类型, 0 - 升序, 1 - 降序

@strWhere      查询条件(注意: 不要加where)

*/

CREATE  PROCEDURE pGO_GetRecordFromPage

@tblName      varchar(255),       -- 表名

@fldName      varchar(255),       -- 字段名

@PageSize     int = 10,           -- 页尺寸

@PageIndex    int = 1,            -- 页码

@IsCount      bit = 0,            -- 返回记录总数, 非0 值则返回

@OrderType    bit = 0,            -- 设置排序类型, 非0 值则降序

@strWhere     varchar(1000) = ''  -- 查询条件(注意: 不要加where)

AS

declare @strSQL   varchar(6000)       -- 主语句

declare @strTmp   varchar(500)        -- 临时变量

declare @strOrder varchar(400)        -- 排序类型

-- 如果是查询记录总数,直接使用Count(0)函数

if @IsCount != 0

begin

if @strWhere != ''

set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere

else

set @strSQL = 'select count(*) as Total from [' + @tblName + '] '

end

--如果是想查询记录,则

else

begin

if @PageIndex = 1

begin

set @strTmp = ''

if @strWhere != ''

set @strTmp = ' where ' + @strWhere

set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

+ @tblName + ']' + @strTmp + ' ' + @strOrder

end

else

begin

--如果是降序查询……

if @OrderType != 0

begin

set @strTmp = '<(select min'

set @strOrder = ' order by [' + @fldName +'] desc'

end

--如果是升序查询……

else

begin

set @strTmp = '>(select max'

set @strOrder = ' order by [' + @fldName +'] asc'

end

if @strWhere != ''

set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

+ @tblName + '] where [' + @fldName + ']' + @strTmp + '(['

+ @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['

+ @fldName + '] from [' + @tblName + '] where ' + @strWhere + ' '

+ @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder

else

set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

+ @tblName + '] where [' + @fldName + ']' + @strTmp + '(['

+ @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['

+ @fldName + '] from [' + @tblName + ']' + @strOrder + ') as tblTmp)'

+ @strOrder

end

end

exec (@strSQL)

GO

http://blog.csdn.net/evafly920/archive/2006/03/03/614813.ASPx

/*

***************************************************************

** 千万数量级分页存储过程**

***************************************************************

参数说明:

1.Tables :表名称,视图

2.PrimaryKey :主关键字

3.Sort :排序语句,不带Order By 比如:NewsID Desc,OrderRows Asc

4.CurrentPage :当前页码

5.PageSize :分页尺寸

6.Filter :过滤语句,不带Where

7.Group :Group语句,不带Group By

效果演示:http://www.cn5135.com/_App/Enterprise/QueryResult.aspx

***************************************************************/

CREATE PROCEDURE CN5135_SP_Pagination

(

@Tables varchar(1000),

@PrimaryKey varchar(100),

@Sort varchar(200) = NULL,

@CurrentPage int = 1,

@PageSize int = 10,

@Fields varchar(1000) = '*',

@Filter varchar(1000) = NULL,

@Group varchar(1000) = NULL

)

AS

/*默认排序*/

IF @Sort IS NULL OR @Sort = ''

SET @Sort = @PrimaryKey

DECLARE @SortTable varchar(100)

DECLARE @SortName varchar(100)

DECLARE @strSortColumn varchar(200)

DECLARE @operator char(2)

DECLARE @type varchar(100)

DECLARE @prec int

/*设定排序语句.*/

IF CHARINDEX('DESC',@Sort)>0

BEGIN

SET @strSortColumn = REPLACE(@Sort, 'DESC', '')

SET @operator = '<='

END

ELSE

BEGIN

IF CHARINDEX('ASC', @Sort) = 0

SET @strSortColumn = REPLACE(@Sort, 'ASC', '')

SET @operator = '>='

END

IF CHARINDEX('.', @strSortColumn) > 0

BEGIN

SET @SortTable = SUBSTRING(@strSortColumn, 0, CHARINDEX('.',@strSortColumn))

SET @SortName = SUBSTRING(@strSortColumn, CHARINDEX('.',@strSortColumn) + 1, LEN(@strSortColumn))

END

ELSE

BEGIN

SET @SortTable = @Tables

SET @SortName = @strSortColumn

END

SELECT @type=t.name, @prec=c.prec

FROM sysobjects o

JOIN syscolumns c on o.id=c.id

JOIN systypes t on c.xusertype=t.xusertype

WHERE o.name = @SortTable AND c.name = @SortName

IF CHARINDEX('char', @type) > 0

SET @type = @type + '(' + CAST(@prec AS varchar) + ')'

DECLARE @strPageSize varchar(50)

DECLARE @strStartRow varchar(50)

DECLARE @strFilter varchar(1000)

DECLARE @strSimpleFilter varchar(1000)

DECLARE @strGroup varchar(1000)

/*默认当前页*/

IF @CurrentPage < 1

SET @CurrentPage = 1

/*设置分页参数.*/

SET @strPageSize = CAST(@PageSize AS varchar(50))

SET @strStartRow = CAST(((@CurrentPage - 1)*@PageSize + 1) AS varchar(50))

/*筛选以及分组语句.*/

IF @Filter IS NOT NULL AND @Filter != ''

BEGIN

SET @strFilter = ' WHERE ' + @Filter + ' '

SET @strSimpleFilter = ' AND ' + @Filter + ' '

END

ELSE

BEGIN

SET @strSimpleFilter = ''

SET @strFilter = ''

END

IF @Group IS NOT NULL AND @Group != ''

SET @strGroup = ' GROUP BY ' + @Group + ' '

ELSE

SET @strGroup = ''

/*执行查询语句*/

EXEC(

'

DECLARE @SortColumn ' + @type + '

SET ROWCOUNT ' + @strStartRow + '

SELECT @SortColumn=' + @strSortColumn + ' FROM ' + @Tables + @strFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '

SET ROWCOUNT ' + @strPageSize + '

SELECT ' + @Fields + ' FROM ' + @Tables + ' WHERE ' + @strSortColumn + @operator + ' @SortColumn ' + @strSimpleFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '

'

)

GO

http://www.qqgb.com/DataDB/MSSQL/sqlMemory/DataDB_116339.html

/*
说明:1.支持多表查询 2.支持任意排序 3.不支持表别名
参考了
    evafly920:[分享]千万数量级分页存储过程(效果演示)
    地址:http://blog.csdn.net/evafly920/archive/2006/03/03/614813.ASPx

IF(EXISTS(SELECT * FROM sysobjects WHERE [id]=OBJECT_ID('usp_PagingLarge') AND xtype='P'))

DROP PROCEDURE usp_PagingLarge

*/

GO

CREATE PROCEDURE usp_PagingLarge

@TableNames VARCHAR(200),    --表名,可以是多个表,但不能用别名

@PrimaryKey VARCHAR(100),    --主键,可以为空,但@Order为空时该值不能为空

@Fields    VARCHAR(200),        --要取出的字段,可以是多个表的字段,可以为空,为空表示select *

@PageSize INT,            --每页记录数

@CurrentPage INT,        --当前页,表示第页

@Filter VARCHAR(200) = '',    --条件,可以为空,不用填where

@Group VARCHAR(200) = '',    --分组依据,可以为空,不用填group by

@Order VARCHAR(200) = ''    --排序,可以为空,为空默认按主键升序排列,不用填order by

AS

BEGIN

DECLARE @SortColumn VARCHAR(200)

DECLARE @Operator CHAR(2)

DECLARE @SortTable VARCHAR(200)

DECLARE @SortName VARCHAR(200)

IF @Fields = ''

SET @Fields = '*'

IF @Filter = ''

SET @Filter = 'WHERE 1=1'

ELSE

SET @Filter = 'WHERE ' + @Filter

IF @Group <>''

SET @Group = 'GROUP BY ' + @Group

IF @Order <> ''

BEGIN

DECLARE @pos1 INT, @pos2 INT

SET @Order = REPLACE(REPLACE(@Order, ' asc', ' ASC'), ' desc', ' DESC')

IF CHARINDEX(' DESC', @Order) > 0

IF CHARINDEX(' ASC', @Order) > 0

BEGIN

IF CHARINDEX(' DESC', @Order) < CHARINDEX(' ASC', @Order)

SET @Operator = '<='

ELSE

SET @Operator = '>='

END

ELSE

SET @Operator = '<='

ELSE

SET @Operator = '>='

SET @SortColumn = REPLACE(REPLACE(REPLACE(@Order, ' ASC', ''), ' DESC', ''), ' ', '')

SET @pos1 = CHARINDEX(',', @SortColumn)

IF @pos1 > 0

SET @SortColumn = SUBSTRING(@SortColumn, 1, @pos1-1)

SET @pos2 = CHARINDEX('.', @SortColumn)

IF @pos2 > 0

BEGIN

SET @SortTable = SUBSTRING(@SortColumn, 1, @pos2-1)

IF @pos1 > 0

SET @SortName = SUBSTRING(@SortColumn, @pos2+1, @pos1-@pos2-1)

ELSE

SET @SortName = SUBSTRING(@SortColumn, @pos2+1, LEN(@SortColumn)-@pos2)

END

ELSE

BEGIN

SET @SortTable = @TableNames

SET @SortName = @SortColumn

END

END

ELSE

BEGIN

SET @SortColumn = @PrimaryKey

SET @SortTable = @TableNames

SET @SortName = @SortColumn

SET @Order = @SortColumn

SET @Operator = '>='

END

DECLARE @type varchar(50)

DECLARE @prec int

SELECT @type=t.name, @prec=c.prec

FROM sysobjects o

JOIN syscolumns c on o.id=c.id

JOIN systypes t on c.xusertype=t.xusertype

WHERE o.name = @SortTable AND c.name = @SortName

IF CHARINDEX('char', @type) > 0

SET @type = @type + '(' + CAST(@prec AS varchar) + ')'

DECLARE @TopRows INT

SET @TopRows = @PageSize * @CurrentPage + 1

print @TopRows

print @Operator

EXEC('

DECLARE @SortColumnBegin ' + @type + '

SET ROWCOUNT ' + @TopRows + '

SELECT @SortColumnBegin=' + @SortColumn + ' FROM  ' + @TableNames + ' ' + @Filter + ' ' + @Group + ' ORDER BY ' + @Order + '

SET ROWCOUNT ' + @PageSize + '

SELECT ' + @Fields + ' FROM  ' + @TableNames + ' ' + @Filter + ' AND ' + @SortColumn + '' + @Operator + '@SortColumnBegin ' + @Group + ' ORDER BY ' + @Order + '

')

END

GO

--调用例子:

--1.单表/单排序

EXEC usp_PagingLarge 'bigtable','d_id','d_id,d_title,d_content,d_time',20,1,'','','d_id desc'

--2.单表/多排序

EXEC usp_PagingLarge 'bigtable','d_id','*',20,0,'','','d_time asc,d_id desc'

--3.多表/单排序

EXEC usp_PagingLarge 'bigtable left join bigtable_author on bigtable.d_id=bigtable_author.BigTable_id', 'bigtable.d_id', 'bigtable.d_id,bigtable.d_title,bigtable.d_content,bigtable.d_time,bigtable_author.d_author', 20, 0, '', '', 'bigtable.d_id asc'

--4.多表/多排序

EXEC usp_PagingLarge 'bigtable left join bigtable_author on bigtable.d_id=bigtable_author.BigTable_id', 'bigtable.d_id', 'bigtable.d_id,bigtable.d_title,bigtable.d_content,bigtable.d_time,bigtable_author.d_author', 20, 0, '', '', 'bigtable.d_time asc,bigtable.d_id desc'

与自定义分页结合例子:

http://bbs.blueidea.com/thread-2720032-1-1.html

Create  Proc proc_PageRecordset

@queryStr nvarchar(2000), --查询语句,用来获取要显示的数据必须满足的要求@keyField nvarchar (72), --主键

@pageSize int, --每页的行数@pageNumber int, --第几页

@filter varChar(2000)='', --过滤,where后头的语句

@order varChar(200)='' --排序方式AS

BEGIN

DECLARE @sqlText AS nvarchar(4000)

DECLARE @sqlTable AS nvarchar(4000)

DECLARE @sqlText_PageCount AS nvarchar(4000)

set @filter=replace(@filter,'#','''')

--这是最后一次所发现的bug,因为在排序中必须确定一个排出来的位置一样的table,不能让a在这次排第,那次又排第

if CharIndex(@keyField,@order)=0

Begin

Set @order=@order+','+@keyField

End

if (Rtrim(@filter)='')

begin

SET @sqlTable = 'SELECT TOP ' + CAST((@pageNumber + 1) * @pageSize AS varchar(30)) + ' ' + @queryStr + ' ' + @order

SET @sqlText_PageCount = 'Select Count(*) from (select ' +@queryStr+ ' ) as Table_temp'

end

else

begin

SET @sqlTable = 'SELECT TOP ' + CAST((@pageNumber + 1) * @pageSize AS varchar(30)) + ' ' + @queryStr + ' and ' + @filter + @order

SET @sqlText_PageCount = 'Select Count(*) AS MyCount from (select ' +@queryStr+ ' and ' + @filter +' ) as Table_temp'

end

--譬如现在要第页数据,每页是行,那么现在要的数据就是在前行,并且不在原来的行内的

SET @sqlText =

'SELECT TOP ' + CAST(@pageSize AS varchar(30)) + ' * ' +

'FROM (' + @sqlTable + ') AS tableA ' +

'WHERE ' + @keyField + ' NOT IN(SELECT TOP ' +

CAST(@pageNumber * @pageSize AS varchar(30)) + ' ' + @keyField +

' FROM (' + @sqlTable + ') AS tableB)'

EXEC (@sqlText)

exec (@sqlText_PageCount)

END

GO

用SQLSERVER未公开的存储过程实现

/**//****** 对象:  StoredProcedure [dbo].[SplitPage]    脚本日期: 04/23/2007 16:10:08 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE procedure [dbo].[SplitPage]

(

@SelectCommandText nvarchar(4000), -- 要执行的查询命令

@CurrentPageIndex int = 0, -- 当前页的索引,从0 开始

@PageSize int = 20, -- 每页的记录数

@RowCount int = 0 out, -- 总的记录数

@PageCount int = 0 out -- 总的页数

)

AS

SET NOCOUNT ON

DECLARE @p1 int

SET @CurrentPageIndex = @CurrentPageIndex + 1

EXEC    sp_cursoropen

@p1 output,

@SelectCommandText,

@scrollopt = 1,

@ccopt = 1,

@RowCount = @RowCount output;

SELECT @RowCount;

SELECT @PageCount = ceiling(1.0 * @RowCount / @PageSize);

SELECT @CurrentPageIndex = (@CurrentPageIndex - 1) * @PageSize + 1

EXEC    sp_cursorfetch

@p1,

16,

@CurrentPageIndex,

@PageSize;

EXEC    sp_cursorclose

@p1

调用方法:

DECLARE    @return_value int,

@RowCount int,

@PageCount int

EXEC    @return_value = [dbo].[SplitPage]

@SelectCommandText = N'SELECT * FROM Log',

@CurrentPageIndex = 0,

@PageSize = 4,

@RowCount = @RowCount OUTPUT,

@PageCount = @PageCount OUTPUT

SELECT    @RowCount as N'@RowCount',

@PageCount as N'@PageCount'

SELECT    'Return Value' = @return_value

GO

CSDN sqlserver 大版主zhoujian的存储过程

/*--用存储过程实现的分页程序

显示指定表、视图、查询结果的第X页

对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法

如果视图或查询结果中有主键,不推荐此方法

*/

/*--调用示例

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) --连接字段

,@strwhere nvarchar(2000) --查询条件

select @Obj_ID=object_id(@QueryStr)

,@FdShow=case isnull(@FdShow,'') when '' then ' *' else ' '+@FdShow end

,@FdOrder=case isnull(@FdOrder,'') when '' then '' else ' order by '+@FdOrder end

,@QueryStr=case when @Obj_ID is not null then ' '+@QueryStr else ' ('+@QueryStr+') a' end

--如果显示第一页,可以直接用top来完成

if @PageCurrent=1

begin

select @Id1=cast(@PageSize as varchar(20))

exec('select top '+@Id1+@FdShow+' from '+@QueryStr+@FdOrder)

return

end

--如果是表,则检查表中是否有标识更或主键

if @Obj_ID is not null and objectproperty(@Obj_ID,'IsTable')=1

begin

select @Id1=cast(@PageSize as varchar(20))

,@Id2=cast((@PageCurrent-1)*@PageSize as varchar(20))

select @FdName=name from syscolumns where id=@Obj_ID and status=0x80

if @@rowcount=0    --如果表中无标识列,则检查表中是否有主键

begin

if not exists(select 1 from sysobjects where parent_obj=@Obj_ID and xtype='PK')

goto lbusetemp   --如果表中无主键,则用临时表处理

select @FdName=name from syscolumns where id=@Obj_ID and colid in(

select colid from sysindexkeys where @Obj_ID=id and indid in(

select indid from sysindexes where @Obj_ID=id and name in(

select name from sysobjects where xtype='PK' and parent_obj=@Obj_ID

)))

if @@rowcount>1   --检查表中的主键是否为复合主键

begin

select @strfd='',@strjoin='',@strwhere=''

select @strfd=@strfd+',['+name+']'

,@strjoin=@strjoin+' and a.['+name+']=b.['+name+']'

,@strwhere=@strwhere+' and b.['+name+'] is null'

from syscolumns where id=@Obj_ID and colid in(

select colid from sysindexkeys where @Obj_ID=id and indid in(

select indid from sysindexes where @Obj_ID=id and name in(

select name from sysobjects where xtype='PK' and parent_obj=@Obj_ID

)))

select @strfd=substring(@strfd,2,2000)

,@strjoin=substring(@strjoin,5,4000)

,@strwhere=substring(@strwhere,5,4000)

goto lbusepk

end

end

end

else

goto lbusetemp

/*--使用标识列或主键为单一字段的处理方法--*/

lbuseidentity:

exec('select top '+@Id1+@FdShow+' from '+@QueryStr

+' where '+@FdName+' not in(select top '

+@Id2+' '+@FdName+' from '+@QueryStr+@FdOrder

+')'+@FdOrder

)

return

/*--表中有复合主键的处理方法--*/

lbusepk:

exec('select '+@FdShow+' from(select top '+@Id1+' a.* from

(select top 100 percent * from '+@QueryStr+@FdOrder+') a

left join (select top '+@Id2+' '+@strfd+'

from '+@QueryStr+@FdOrder+') b on '+@strjoin+'

where '+@strwhere+') a'

)

return

/*--用临时表处理的方法--*/

lbusetemp:

select @FdName='[ID_'+cast(newid() as varchar(40))+']'

,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(20))

,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(20))

exec('select '+@FdName+'=identity(int,0,1),'+@FdShow+'

into #tb from'+@QueryStr+@FdOrder+'

select '+@FdShow+' from #tb where '+@FdName+' between '

+@Id1+' and '+@Id2

)

GO

ORACLE SQLSERVER2005分页相关推荐

  1. Oracle中分页查询语句

    Oracle分页查询语句使我们最常用的语句之一,下面就为您介绍的Oracle分页查询语句的用法,如果您对此方面感兴趣的话,不妨一看. Oracle分页查询语句基本上可以按照本文给出的格式来进行套用. ...

  2. oracle分页的方法,Oracle数据库分页的集中方法(三种方法)

    在 做项目中用到了分页,下面说一下oracle分页的方法; 采用伪列 rownum 查询前10条记录 [sql] select * from t_user t where ROWNUM <10; ...

  3. oracle在日期区间分页查询,Oracle 日期分页

    1.[代码]Oracle日期和分页 select * from li.books where book_publish_date between '1-2月-2005' and '1-2月-2010' ...

  4. Oracle之分页查询

    2019独角兽企业重金招聘Python工程师标准>>> Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. 分页查询格式 SELECT * FROM ( SELECT ...

  5. C#调用Oracle存储过程分页

    直接调用Oracle中的存储过程完成对表的分页,对代码封闭程度高,执行高效.以下为C#分页类代码,包括Oracle数据库 端存储过程PLSQL代码. //    程序调用示例: // int tota ...

  6. oracle sql 分页

    Oracle实现分页时,需要引入一个rownum的函数,rownum可以给记录一个类似于id的字段. 以下收整理了常用的几种sql分页算法,数据库以Oracle中emp为例.查询结果如下: SQL&g ...

  7. Oracle的分页实现

    转载自  Oracle的分页实现 在Oracle中实现分页的方法大致分为两种,用ROWNUM关键字和用ROWID关键字,下面来详细介绍一下: 1.ROWNUM 其代码为: SELECT *FROM ( ...

  8. oracle高效分页查询总结

    本文参考链接:http://blog.sina.com.cn/s/blog_8604ca230100vro9.html 探索查询语句: --分页参数:size = 20 page = 2 --没有or ...

  9. Oracle数据库分页总结

    在Oracle数据库中,数据分页功能是必不可少的操作, Oracle数据库分页查询语句有三种写法: --1.根据ROWID 来分 select * from nmb where rowid in( s ...

最新文章

  1. Vue中数组赋值问题
  2. 微信小程序学习笔记(五)
  3. java web 多语言_基于 Selenium WebDriver 实现多语言环境下自动化截图
  4. POSIX 条件变量
  5. L1-019 谁先倒 (15 分) — 团体程序设计天梯赛
  6. 价格穿越,跟 普通的大于 小于是有差别的
  7. 跟进分析不一样的MTI商城
  8. python画画excel_用Python在Excel里画出蒙娜丽莎
  9. 2017网易校招:数字游戏
  10. 网站收录的是域名还是服务器,网站备案的到底域名还是服务器?
  11. “不靠谱“的布隆过滤器是怎么成为大数据世界中的韦小宝的?
  12. react navigation 中使用goBack()跳转到指定页面
  13. Red Hat Enterprise Linux 5.1 Server(正式版)各版本下载2011-04-17 22:21
  14. java并发编程中常用的工具类 Executor
  15. python用循环结构求平均值_有python的输出问题;循环总数和平均值
  16. c语言幸运数字程序设计,c语言实现:4和7幸运数字的题
  17. 试试smartdraw
  18. 剑指Offer 24 反转链表
  19. java毕业设计_银行账目管理系统
  20. 【2023注册测绘师考试综合能力考试攻略】 ——摄影测量与遥感的考点试题汇编及参考答案

热门文章

  1. php比较两个数组的键名统计有交集的数量,php比较两个数组的键名并返回交集的函数array_intersect_key()...
  2. ovirt 双机_ovirt kvm嵌套虚拟化
  3. create报错不是函数_各种SQL中关于日期函数的那些事(建议收藏)
  4. netty 多个 本地udp端口_如何在SpringBoot中,使用Netty实现远程调用?
  5. js设置控件的隐藏与显示的两种方法
  6. Spark基础学习笔记06:搭建Spark On YARN模式的集群
  7. 安卓案例:使用AChartEngine绘制折线图
  8. 安卓学习笔记02:测试安卓开发环境
  9. Java Web学习笔记11:JSTL与EL
  10. 提出邀请Do you want..._43