千万数量级分页存储过程

GO
/****** Object: StoredProcedure [dbo].[PR_Page] Script Date: 05/09/2019 09:53:54 /
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
------------------------------------------------------------------分页存储过程------------------------------------------------------------
ALTER PROCEDURE [dbo].[PR_Page]
/
********************************************************
** 千万数量级分页存储过程 **
**************************************************************/
(
@Tables varchar(1000), --1.Tables :表名称,视图, 可为多个多个表之间用逗号分隔,别名和表名之间以一个空格 AS 别名分隔 ,
@PrimaryKey varchar(300), --2.PrimaryKey :主关键字 对应各表的关键字,可加前缀如a.id,b.name,以逗号分隔各关键字
@LinkKey varchar(1000), --3.@LinkKey 各表之间的关联关系 如 EMP a join AUTHOR b on a.id=b.id left join BOOK C ON c.id=a.id and c.id=b.id
@Fields varchar(3000) = '
’, --4.Fields :显示的字段
@Filter varchar(2000) = NULL, --5.Filter :条件语句,不带Where
@Sort varchar(300) = NULL, --6.Sort :排序语句,不带Order By 比如:NewsID Desc,OrderRows Asc
@Group varchar(1000) = NULL, --7.Group :Group语句,不带Group By
@CurrentPage int = 1, --8.CurrentPage :当前页码
@PageSize int = 10, --9.PageSize :分页尺寸
@RecordCount int =0 OUTPUT --10.@RecordCount 输出总记录数
)
AS
BEGIN
declare @SortTable varchar(200) --排序表
declare @Coltype varchar(200) --排序列名
declare @prec int,@SpaceAs int
declare @iCountTable int ,@iColLen int
declare @TempTables varchar(2000),@TempKeys varchar(300),@TempName varchar(100)
declare @temp varchar(100), @AliasName varchar(100),@TempKey varchar(100) ,@TempTableKEY varchar(100)
declare @StrDeclare varchar(500);
declare @StrFields varchar(3000);
declare @I INT;
declare @SCon varchar(3000);
declare @SCon1 varchar(1000), @SCon2 varchar(1000),@sTemp varchar(1000)
declare @StrOrder varchar(500)
declare @AliasName1 varchar(500);
declare @sSQL varchar(8000)
declare @sFilter varchar(2000)
declare @sOrder varchar(1000)
declare @strPageSize varchar(10)
declare @strStartRow varchar(10)
declare @sqlsCount nvarchar(4000)
declare @sGroup varchar(500)
declare @Opt int
declare @num int
CREATE TABLE #TempTable (TableName varchar(100), AliasName varchar(100))
CREATE TABLE #TempTableKEY (A1 int IDENTITY (1, 1) NOT NULL,TableName varchar(100), AliasName varchar(100),
COLName varchar(100), ColType varchar(50), ColLen integer, opt int DEFAULT (0))

/********************************该处分隔多个表名信息*******************************/
--set @TempTables=ltrim(rtrim(@Tables))
set @TempTables=ltrim(rtrim(@Tables))+','
set @prec=CHARINDEX(',', @TempTables)
set @iCountTable=1;

while @prec > 0
begin
	set @temp = rtrim(ltrim(left(@TempTables,@prec-1)));
	set @TempTables=rtrim(ltrim(right(@TempTables,len(@TempTables)-@prec)));
	/*******取出表名信息以及别名信息*****/
	set @SpaceAs= charIndex(' AS ',upper(@temp))
	if @SpaceAs>0
	begin
		set @AliasName= rtrim(ltrim(right(@temp,len(@temp)-@SpaceAs-3)));
		set @temp=rtrim(ltrim(left(@temp,@SpaceAs-1)));
	end
	else 
	begin   
		set @SpaceAs= charIndex(' ',@temp)
		if @SpaceAs>0
		begin
			set @AliasName= rtrim(ltrim(right(@temp,len(@temp)-@SpaceAs+1)));
	  		set @temp=rtrim(ltrim(left(@temp,@SpaceAs-1)));
		end
		else
			set @AliasName=@temp;
	end
	insert into #TempTable values(@temp,@AliasName);
	
	--print '@TempName ='+@temp + ' AliasName='+@AliasName
	--print '@iCountTable='+cast(@iCountTable as varchar(10));
	--继续取得下个表名信息
	set @prec=CHARINDEX(',', @TempTables)
	set @iCountTable=@iCountTable+1;
end
/**********************************该处分隔多个排序字段名信息***************************************/
if @Sort IS NOT NULL AND rtrim(ltrim(@Sort)) != ''
begin	
	--set @TempTableKEY=ltrim(rtrim(@Sort))
	set @TempTableKEY=ltrim(rtrim(@Sort))+','
	set @prec=CHARINDEX(',', @TempTableKEY)
	set @opt=0;

	while @prec > 0
	begin
		set @temp = rtrim(ltrim(left(@TempTableKEY,@prec-1)));--逗号之前部分
		set @TempTableKEY=rtrim(ltrim(right(@TempTableKEY,len(@TempTableKEY)-@prec)));--逗号之后部分
		/*******取出排序字段名信息以及表别名信息*****/
		set @SpaceAs= charIndex('.',@temp)
		if @SpaceAs>0
		begin
            set @TempKey= rtrim(ltrim(right(@temp,len(@temp)-@SpaceAs)));--字段名 含DESC 或者ASC 
			set @AliasName=rtrim(ltrim(left(@temp,@SpaceAs-1)));         --表别名
		end
		else			
		begin		
			set @TempKey= rtrim(ltrim(@temp))
			set @AliasName='';
		end
		/***********************判断正序 倒序********************/
		set @SpaceAs= charIndex(' DESC',UPPER(@TempKey))
		if @SpaceAs>0
		begin
            set @TempKey= left(rtrim(ltrim(@TempKey)),@SpaceAs-1); --去除DESC或者ASC
			set @Opt=1
			--print '@TempKey==='+@TempKey;
		end
		else			
		begin		
			set @SpaceAs= charIndex(' ASC',UPPER(@TempKey))
			if @SpaceAs>0
				set @TempKey= left(rtrim(ltrim(@TempKey)),@SpaceAs-1); --去除DESC或者ASC
			set @Opt=0
			--print '@TempKey======='+@TempKey;
		end

		select @TempName=TableName from #TempTable 
		where tablename=@AliasName or AliasName=@AliasName or (@AliasName='' and tablename=AliasName)

		SELECT @Coltype=t.name, @iColLen=c.prec
		FROM sysobjects o 
		JOIN syscolumns c on o.id=c.id
		JOIN systypes t on c.xusertype=t.xusertype
		WHERE o.name = @TempName AND c.name = @TempKey

		insert into #TempTableKEY (TableName, AliasName ,COLName, ColType, ColLen, opt)
			values(@TempName, @AliasName, @TempKey, @Coltype,@iColLen,@opt);
		
		--继续取得下个表名信息
		set @prec=CHARINDEX(',', @TempTableKEY)
	end
end


/**********************************该处分隔多个主键名信息***************************************/
--set @TempTableKEY=ltrim(rtrim(@PrimaryKey))
set @TempTableKEY=ltrim(rtrim(@PrimaryKey))+','
set @prec=CHARINDEX(',', @TempTableKEY)
set @opt=0;
while @prec > 0
begin
	set @temp = rtrim(ltrim(left(@TempTableKEY,@prec-1)));
	set @TempTableKEY=rtrim(ltrim(right(@TempTableKEY,len(@TempTableKEY)-@prec)));
	/*******取出主键名信息以及表别名信息*****/
	set @SpaceAs= charIndex('.',@temp)
	if @SpaceAs>0
	begin
        set @TempKey= rtrim(ltrim(right(@temp,len(@temp)-@SpaceAs)));
		set @AliasName=rtrim(ltrim(left(@temp,@SpaceAs-1)));
	end
	else			
	begin		
		set @TempKey= rtrim(ltrim(@temp))
		set @AliasName='';
	end

	select @TempName=TableName from #TempTable 
	where tablename=@AliasName or AliasName=@AliasName or (@AliasName='' and tablename=AliasName)
	if not exists(select * from #TempTableKEY where  TableName=@TempName and  COLName=@TempKey)
	begin
		SELECT @Coltype=t.name, @iColLen=c.prec
		FROM sysobjects o 
		JOIN syscolumns c on o.id=c.id
		JOIN systypes t on c.xusertype=t.xusertype
		WHERE o.name = @TempName AND c.name = @TempKey

		insert into #TempTableKEY (TableName, AliasName,COLName, ColType, ColLen, opt)
			values(@TempName,@AliasName, @TempKey, @Coltype,@iColLen,@opt);
	end
	--继续取得下个表名信息
	set @prec=CHARINDEX(',', @TempTableKEY)
end

/*****************************根据临时表的主键定义变量******************************/
DECLARE TempKeyCursor CURSOR FOR 
	Select a.TableName,a.COLName,a.ColType,a.ColLen,AliasName ,A.opt
	From  #TempTableKEY a 
	ORDER BY A.A1
open TempKeyCursor ;
declare @sOpt varchar(2);
SET @I=0;
set @StrFields=''
set @StrDeclare=''
set @SCon=''
set @SCon1=''
set @SCon2=''
set @Stemp=''
set @StrOrder=' '
SET @OPT=0;
FETCH NEXT FROM TempKeyCursor INTO @TempName,@TempKey, @Coltype, @iColLen, @AliasName,@OPT

WHILE @@FETCH_STATUS = 0
BEGIN
	IF CHARINDEX('char', @Coltype) > 0
		SET @Coltype = @Coltype + '(' + CAST(@iColLen AS varchar) + ')'
	set @StrDeclare=@StrDeclare+'
	declare @SORTKEY'+CAST(@I AS VARCHAR(5))+ ' '+@Coltype;
	if @AliasName=''
		set @AliasName1=@TempKey
	else
		set @AliasName1=@AliasName+'.'+@TempKey
	set @StrFields=@StrFields+'@SORTKEY'+CAST(@I AS VARCHAR(5))+'=isnull('+@AliasName1+',''''),'
	
	if @OPT=0 
	BEGIN
		set @sOPT='>'
		set @StrOrder=@StrOrder+'isnull('+@AliasName1+','''') ,'
	END
	else 
	BEGIN
		set @sOPT='<'
		set @StrOrder=@StrOrder+'isnull('+@AliasName1+','''') DESC,'
	END

	FETCH NEXT FROM TempKeyCursor INTO @TempName,@TempKey, @Coltype, @iColLen, @AliasName,@opt
	set @sTemp=@sCon1;
	if @@FETCH_STATUS<0 
	begin
		set @sCon1= ''
		if @sTemp<>''
			set @sCon2= @sTemp+' and isnull('+@AliasName1+','''')'+ @sOpt+'='+'@SORTKEY'+CAST(@I AS VARCHAR(5))
		else
			set @sCon2='isnull('+@AliasName1+','''')'+ @sOpt+'='+'@SORTKEY'+CAST(@I AS VARCHAR(5))
	end
	else
	begin
		if @sTemp<>''
		begin
			set @sCon1=@sTemp+' and isnull('+@AliasName1+','''')='+'@SORTKEY'+CAST(@I AS VARCHAR(5))
			set @sCon2=@sTemp+' and isnull('+@AliasName1+','''')'+ @sOpt+'@SORTKEY'+CAST(@I AS VARCHAR(5))
		end
		else
		begin
			set @sCon1='isnull('+@AliasName1+','''')='+'@SORTKEY'+CAST(@I AS VARCHAR(5))
			set @sCon2='isnull('+@AliasName1+','''')'+ @sOpt+'@SORTKEY'+CAST(@I AS VARCHAR(5))
		end
	end
	if @sCon='' 
		set @sCon=@sCon2
	else
		set @sCon=@Scon+' or ('+@sCon2+')'; 
	set @I=@I+1
END
set @SCon=' and ('+@SCon+')'
CLOSE TempKeyCursor
DEALLOCATE TempKeyCursor

/*设置分页参数.*/
IF @CurrentPage < 1
	SET @CurrentPage = 1	
SET @strPageSize = CAST(@PageSize AS varchar(10))
SET @strStartRow = CAST(((@CurrentPage - 1) * @PageSize + 1) AS varchar(10))
/*筛选以及分组语句.*/
IF @Filter IS NOT NULL AND  rtrim(ltrim(@Filter)) != ''
	SET @sFilter = ' WHERE ' + @Filter + ' '
ELSE
	SET @sFilter = ' WHERE 1=1 '
set @StrOrder=left(@StrOrder,len(@StrOrder)-1)
set @sOrder=' ORDER BY '+ @StrOrder
if @GROUP IS NOT NULL AND  rtrim(ltrim(@GROUP)) != '' 
	set @sGroup=' GROUP BY '+@GROUP
ELSE 
	set @sGroup=''

set @StrFields =left(@StrFields,len(@StrFields)-1)
set @sSQL = @StrDeclare+'
	SET ROWCOUNT ' + @strStartRow + '
	SELECT '+ @StrFields + ' from '+@LinkKey + @sFilter +@sGroup +@sOrder+' 
	SET ROWCOUNT ' + @strPageSize + '
	SELECT '+ @Fields + ' from '+@LinkKey +@sFilter + @SCon  + ' '  +@sGroup +  @sOrder + ''
--返回的结果集
--print @SSQL;
EXEC(@sSQL);
--计算记录总数量
    if @Group<>''
  begin
      set @sqlsCount=N'SELECT @Count=count(*) FROM (select count(*) a from ' + @LinkKey + @sFilter+ 'group by '+@Group+') a';
  end
    else
      begin
         set @sqlsCount=N'SELECT @Count=count(*) FROM ' + @LinkKey + @sFilter;
      end
execute sp_executesql 
	@sqlsCount,    --执行上面的sql语句
	N'@Count int OUTPUT' ,   --执行输出数据的sql语句,output出总记录数
	@RecordCount  OUTPUT
SET ROWCOUNT 0

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值