zoukankan      html  css  js  c++  java
  • MSSQL 分页

    使用数据库分页返回用户数据有如下好处:
    1、减少服务器磁盘系统地读取压力
    2、减少网络流量,减轻网络压力
    3、减轻客户端显示数据的压力
    4、提高处理效率。

    一般而言分页处理分为两种:应用程序中的分页(查询出所有数据)处理和数据库中的分页处理。目前大多数的应用都是在应用程序中借助支持数据分页处理的数据库访问组件(如DataGrid控件)实现分页处理(大部分的分页插件中也是采用的程序分页)。实际上,在数据库中实现分页处理,可以从源头减少数据处理量,效果往往可能更好。

    所以我们在需要分页的时候尽量使用数据库分页效果是更好的。

    常规的取第n页数据方法为

    SELECT TOP PageSize * FROM TableA WHERE Primary_Key NOT IN (SELECT TOP (n-1) * PageSize Primary_Key FROM TableA )  

    这样的如果改成存储过程大概是这样的

    CREATE PROC up_PageView ( @tableName SYSNAME ,
                              @colKey NVARCHAR(100) ,
                              @pageCurrent INT = 1 ,
                              @pageSize INT = 10 ,
                              @colShow NVARCHAR(4000) = '' ,
                              @colOrder NVARCHAR(200) = '' ,
                              @where NVARCHAR(2000) = '' ,
                              @pageCount INT OUTPUT )
    AS 
       BEGIN
          IF OBJECT_ID(@tableName) IS NULL 
             BEGIN
                RAISERROR('the table is not existing!', 16,1)
                RETURN 
             END
          IF ISNULL(@colShow,'') = '' 
             SET @colShow = '*'
          IF ISNULL(@colOrder,'') = '' 
             SET @colOrder = ''
          ELSE 
             SET @colOrder = 'order by ' + @colOrder
          IF ISNULL(@where,'') = '' 
             SET @where = ''
          ELSE 
             SET @where = 'where ' + @where
          DECLARE @sql NVARCHAR(4000)
          IF @pageCount IS NULL 
             BEGIN
                SET @sql = 'select @pageCount = count(*) from ' + @tableName + ' ' + @where
                EXEC sp_executesql 
                   @sql ,
                   '@pageCount int output' ,
                   @pageCount OUTPUT
                SET @pageCount = ( @pageCount + @pageSize - 1 ) / @pageSize -- get total pages
             END
          IF @pageCurrent = 1 
             BEGIN
                SET @sql = N'select top' + N' ' + CONVERT(NVARCHAR(10),@pageSize) + N' ' + @colshow + N' ' + N'from '
                   + @tableName + N' ' + @where + N' ' + @colOrder
                EXEC (@sql)
             END
          ELSE 
             BEGIN
                DECLARE @topN INT ,
                   @topN1 INT
    --        set @topN = @pageSize
    --        set @topN1 = @pageCurrent * @pageSize
                SET @pageCurrent = @pageCurrent * @pageSize
                SET @sql = N'select @n = @n - 1, @s = case when @n < ' + CONVERT(NVARCHAR(10),@pageSize)
                   + N' then @s + '','' + quotename(@colKey, N'''''''') ' + N'else ''''' + N' end ' + N' from ' + @tableName
                   + N' ' + @where
            --make query effect only @pageCurrent records
            --Query only top @pageCurrent * @pageSize
                SET ROWCOUNT @pageCurrent 
                EXEC sp_executesql 
                   @sql ,
                   '@n int, @s nvarchar(max) output' ,
                   @pageCurrent ,
                   @sql OUTPUT
                SET ROWCOUNT 0 --recover to default config
                SET @sql = STUFF(@sql,1,1,N'') -- remove the first ','
            --exec the query
                EXEC (N'select ' + @colShow + N' ' + 'from' + N' ' + @tableName + N' '  
                + N'where ' + @colKey + N' in (' + @sql + ')' + @colOrder)
             END
       END
    go

    但是这种执行起来效率比较低,这样是把 top n 取大量的数据并缓存起来,在关联元表查询出最终结果。

    下面我们采用另一种方法,在 sql server 2005 以后增加了一些新的功能如取得排名或顺序的函数(Rank(), Dense_Rank(), Row_Number()), 利用这些新的功能也能进行分页处理,下面以sql server 2005 自带的数据库AdventureWorks为例结合Row_Number() 实现分页处理:

    CREATE PROC up_GetPagen ( @pageSize INT ,
                              @pageCurrent INT ,
                              @countPage INT OUTPUT )
    AS 
       BEGIN
          SELECT *
             FROM (
                    SELECT ROW_NUMBER () OVER (ORDER BY id) RowNum,* FROM TableA
                  ) TA
             WHERE RowNum BETWEEN ( @pageCurrent - 1 ) * @pageSize + 1 AND @pageCurrent * @pageSize
             ORDER BY Id
             
          --另加一个返回总记录数吧。
          SELECT @countPage = COUNT(0)
             FROM TableA
       END
  • 相关阅读:
    【Canvas】(1)---概述+简单示例
    【jQuery】(8)---jquery Ajax
    lastlogon
    windows server core 2016 IIS远程管理的那些坑
    开机手机显示存储空间不足某些系统功能可能无法正常使用,而且无法取消这个界面,导致手机停在这个界面无法操作。
    javascript prototype理解
    微信小程序诡异错误this.setData报错
    转:goproxy和go modules的初步使用
    真机调试No target device的解决(android studio)3.4.1
    unable to access android sdk add-on list的解决
  • 原文地址:https://www.cnblogs.com/albert-struggle/p/4258890.html
Copyright © 2011-2022 走看看