SqlServer2005中的row_number分页存储过程,支持多表联查

本文介绍了一个SQL Server存储过程,用于实现多表查询的分页功能,并提供了实例代码。此外,还分享了关于SQL Server 2005在处理千万级别数据时的分页优化经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go



/*
支持多表查询分页存储过程(事理改进)2012.3
--多表联查1
declare @Count int
exec [proc_DataPagination] 'SL_Article a,SL_User u','u.RealName,a.*','a.UserId=u.UserId','',1,20,0,@Count output
select @Count
--多表联查2
declare @Count int
exec proc_DataPagination 'SL_LANAndWANPermissionLog l left join SL_Plate p on l.PlateId=p.PlateId left join SL_Admin a on l.AddUserId=a.UserId','l.*,p.PlateName,a.RealName as AddUserRealName','','Id',1,20,0,@Count output
select @Count
*/
/*注意:多表联查,如果两个表有相同的列名,必须指定要查询的列名,不然会报错*/
ALTER PROCEDURE [dbo].[proc_DataPagination]
(
    @Table nvarchar(1000),--表名,支持多表联查
    @Fields varchar(2000) = N'*',--字段名
    @Where nvarchar(4000) = N'',--where条件,不需要加where
    @OrderBy varchar(1000) = N'',--排序条件,不需要加order by
    @CurrentPage int = 1, --当前页,从1开始,不是0
    @PageSize int = 10,--每页显示多少条数据
    @GetCount int =0,--获取的记录总数,0则获取记录总数,不为0则不获取
    @Count int = 0 output--总数
)
AS
BEGIN
    SET NOCOUNT ON
    --没有提供排序字段,默认主键排序
    if @OrderBy is null or @OrderBy=''
    begin
        declare @tempTable varchar(200)
        set @Table=ltrim(rtrim(@Table))--去除开头和尾部空格
        --多表联查如果没有提供排序字段,自动找第一个表的主键进行排序
        if charindex(' on ',@Table)>0
            set @tempTable=substring(@Table,0,charindex(' ',@Table))
        else if charindex(',',@Table)>0
            begin
                set @tempTable=substring(@Table,0,charindex(',',@Table))
                --如果有别名如Article a,User u
                if(charindex(' ',@tempTable)>0)
                    set @tempTable=substring(@tempTable,0,charindex(' ',@tempTable))
            end
        else
            begin
                if(charindex(' ',@Table)>0)--SL_Article a防止只有一个表取别名情况
                    set @tempTable=substring(@Table,0,charindex(' ',@Table))
                else
                    set @tempTable=@Table--单表查询
            end

        --查询表是否存在
        if not exists(select * from sysobjects where [name]=@tempTable)
          begin
            raiserror('查询表%s不存在',12,12,@tempTable)
            return
          end    

        --查询排序主键
        declare @objectid int;Set @objectid=object_id(@tempTable)
        select top 1 @OrderBy=col_name(@objectid,colid) from sysobjects as o 
            Inner Join sysindexes as i On i.name=o.name 
            Inner Join sysindexkeys as k On k.indid=i.indid 
        Where o.xtype = 'PK' and parent_obj=@objectid and k.id=@objectid
        --如果没有主键,如视图
        if @OrderBy is null or @OrderBy = ''
          begin
            raiserror('%s必须在@OrderBy中提供排序字段',12,12,@tempTable)
            return
          end
    end

    --分页大小
    if @PageSize < 1
       set @PageSize=10

    --默认当前页
    if @CurrentPage < 1
        set @CurrentPage = 1

    --选取字段
    if @Fields is null or @Fields = ''
        set @Fields='*'

    --过滤条件
    if @Where is null or @Where=''
        set @Where=''
    else
        set @Where=' WHERE '+@Where

    /*设置分页参数*/
    declare @startRow varchar(50),@endRow varchar(50)
    set @startRow = cast(((@CurrentPage - 1)*@PageSize + 1) as nvarchar(50))
    set @endRow = cast(@CurrentPage*@PageSize as nvarchar(50))
    
    exec
    (
        'SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY '+@OrderBy+') AS rownumber,'+@Fields+
        ' FROM '+@Table+@Where+') AS tempdt WHERE rownumber BETWEEN '+@startRow+' AND '+@endRow
    )

    /*
    如果@GetCount=0,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,
    把总页数传回给存储过程,避免再次计算总页数,当数据量很大时,select count(*)速度也要几秒钟)
    */
    if(@GetCount=0)
      begin
        declare @sql nvarchar(max)
        set @sql='SELECT @i=COUNT(*) FROM '+@Table+@Where    
        execute sp_executesql @sql,N'@i int out',@Count OUT--返回总记录数
      end
    else
        set @Count=@GetCount
END

 

SQL Server 2005 千万条以上记录分页数据库优化经验

https://wenku.baidu.com/view/8ab21eef856a561252d36f99.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值