有关分页存储过程

1------------------------------------------------
--游标不是明智的选择,在小数据量时可以使用
create   procedure hahaha 
  @sqlstr nvarchar(4000), --查询字符串 
  @currentpage int, --第N页 
  @pagesize int --每页行数 
  as 
  set nocount on 
  declare @P1 int, --P1是游标的id 
  @rowcount int 
  exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output 
  select ceiling(1.0*@rowcount/@pagesize) as 总页数--,@rowcount as 总行数,@currentpage as 当前页 
  set @currentpage=(@currentpage-1)*@pagesize+1 
  exec sp_cursorfetch @P1,16,@currentpage,@pagesize   
  exec sp_cursorclose @P1 
  set nocount off 
  
  测试: hahaha '任何条件的SQL语句',2,10 
  
  
  2----------------
  
  
  CREATE PROCEDURE 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(1000)     -- 主语句 
  declare @strTmp   varchar(300)     -- 临时变量 
  declare @strOrder varchar(400)     -- 排序类型 
  
  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 != &apos;&apos; 
    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 != &apos;&apos; 
      set @strTmp = " where (" + @strWhere + ")" 
  
    set @strSQL = "select top " + str(@PageSize) + " * from [" 
      + @tblName + "]" + @strTmp + " " + @strOrder 
  end 
  
  if @IsCount != 0 
    set @strSQL = "select count(*) as Total from [" + @tblName + "]" 
  
  exec (@strSQL) 
  GO 
3--------------------------------




CREATE Proc p_show 
@QueryStr nvarchar(4000), --表名、视图名、查询语句 
@PageSize int=10,   --每页的大小(行数) 
@PageCurrent int=1,   --要显示的页 
@FdShow nvarchar (4000)= &apos; &apos;, --要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段 
@FdOrder nvarchar (1000)= &apos; &apos; --排序字段列表 
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, &apos; &apos;) when &apos; &apos; then &apos; * &apos; else &apos; &apos;+@FdShow end 
  ,@FdOrder=case isnull(@FdOrder, &apos; &apos;) when &apos; &apos; then &apos; &apos; else &apos; order by &apos;+@FdOrder end 
  ,@QueryStr=case when @Obj_ID is not null then &apos; &apos;+@QueryStr else &apos; ( &apos;+@QueryStr+ &apos;) a &apos; end 

--如果显示第一页,可以直接用top来完成 
if @PageCurrent=1 
begin 
  select @Id1=cast(@PageSize as varchar(20)) 
  exec( &apos;select top &apos;+@Id1+@FdShow+ &apos; from &apos;+@QueryStr+@FdOrder) 
  return 
end 

--如果是表,则检查表中是否有标识更或主键 
if @Obj_ID is not null and objectproperty(@Obj_ID, &apos;IsTable &apos;)=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= &apos;PK &apos;) 
  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= &apos;PK &apos; and parent_obj=@Obj_ID 
  ))) 
  if @@rowcount> 1   --检查表中的主键是否为复合主键 
  begin 
  select @strfd= &apos; &apos;,@strjoin= &apos; &apos;,@strwhere= &apos; &apos; 
  select @strfd=@strfd+ &apos;,[ &apos;+name+ &apos;] &apos; 
    ,@strjoin=@strjoin+ &apos; and a.[ &apos;+name+ &apos;]=b.[ &apos;+name+ &apos;] &apos; 
    ,@strwhere=@strwhere+ &apos; and b.[ &apos;+name+ &apos;] is null &apos; 
    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= &apos;PK &apos; 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( &apos;select top &apos;+@Id1+@FdShow+ &apos; from &apos;+@QueryStr 
  + &apos; where &apos;+@FdName+ &apos; not in(select top &apos; 
  +@Id2+ &apos; &apos;+@FdName+ &apos; from &apos;+@QueryStr+@FdOrder 
  + &apos;) &apos;+@FdOrder 
  ) 
  return 

/*--表中有复合主键的处理方法--*/ 
lbusepk:   
  exec( &apos;select &apos;+@FdShow+ &apos; from(select top &apos;+@Id1+ &apos; a.* from 
  (select top 100 percent * from &apos;+@QueryStr+@FdOrder+ &apos;) a 
  left join (select top &apos;+@Id2+ &apos; &apos;+@strfd+ &apos; 
  from &apos;+@QueryStr+@FdOrder+ &apos;) b on &apos;+@strjoin+ &apos; 
  where &apos;+@strwhere+ &apos;) a &apos; 
  ) 
  return 

/*--用临时表处理的方法--*/ 
lbusetemp:   
select @FdName= &apos;[ID_ &apos;+cast(newid() as varchar(40))+ &apos;] &apos; 
  ,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(20)) 
  ,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(20)) 

exec( &apos;select &apos;+@FdName+ &apos;=identity(int,0,1), &apos;+@FdShow+ &apos; 
  into #tb from &apos;+@QueryStr+@FdOrder+ &apos; 
  select &apos;+@FdShow+ &apos; from #tb where &apos;+@FdName+ &apos; between &apos; 
  +@Id1+ &apos; and &apos;+@Id2 
  ) 

GO 


create table ta(col1 int,col2 char(2))
go
insert ta select 1,&apos;2&apos;

exec p_show &apos;(select * from ta)&apos;,10,1,&apos;col1,col2&apos;,&apos;col2&apos;


drop table ta
drop proc p_show

/*

col1    col2 
----------- ---- 
1     2 

(所影响的行数为 1 行)
*/

 
 
 
 
4--TOP n 实现的通用分页排序存储过程
--exec sp_PageView t,&apos;ID&apos;,1,5,&apos;ID,sex,Name&apos;,&apos;ID asc&apos;,&apos;ID=1&apos;,1
CREATE PROC sp_PageView
@tbname   sysname,     --要分页显示的表名
@FieldKey nvarchar(1000),  --用于定位记录的主键(惟一键)字段,可以是逗号分隔的多个字段
@PageCurrent int=1,     --要显示的页码
@PageSize int=10,    --每页的大小(记录数)
@FieldShow nvarchar(1000)=&apos;&apos;,  --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段
@FieldOrder nvarchar(1000)=&apos;&apos;,  --以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC
--用于指定排序顺序
@Where  nvarchar(1000)=&apos;&apos;, --查询条件
@PageCount int OUTPUT   --总页数
AS
SET NOCOUNT ON
--检查对象是否有效
IF OBJECT_ID(@tbname) IS NULL
BEGIN
RAISERROR(N&apos;对象"%s"不存在&apos;,1,16,@tbname)
RETURN
END
IF OBJECTPROPERTY(OBJECT_ID(@tbname),N&apos;IsTable&apos;)=0
AND OBJECTPROPERTY(OBJECT_ID(@tbname),N&apos;IsView&apos;)=0
AND OBJECTPROPERTY(OBJECT_ID(@tbname),N&apos;IsTableFunction&apos;)=0
BEGIN
RAISERROR(N&apos;"%s"不是表、视图或者表值函数&apos;,1,16,@tbname)
RETURN
END

--分页字段检查
IF ISNULL(@FieldKey,N&apos;&apos;)=&apos;&apos;
BEGIN
RAISERROR(N&apos;分页处理需要主键(或者惟一键)&apos;,1,16)
RETURN
END

--其他参数检查及规范
IF ISNULL(@PageCurrent,0)<1 SET @PageCurrent=1
IF ISNULL(@PageSize,0)<1 SET @PageSize=10
IF ISNULL(@FieldShow,N&apos;&apos;)=N&apos;&apos; SET @FieldShow=N&apos;*&apos;
IF ISNULL(@FieldOrder,N&apos;&apos;)=N&apos;&apos;
SET @FieldOrder=N&apos;&apos;
ELSE
SET @FieldOrder=N&apos;ORDER BY &apos;+LTRIM(@FieldOrder)
IF ISNULL(@Where,N&apos;&apos;)=N&apos;&apos;
SET @Where=N&apos;&apos;
ELSE
SET @Where=N&apos;WHERE (&apos;+@Where+N&apos;)&apos;

--如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值)
IF @PageCount IS NULL
BEGIN
DECLARE @sql nvarchar(4000)
SET @sql=N&apos;SELECT @PageCount=COUNT(*)&apos;
+N&apos; FROM &apos;+@tbname
+N&apos; &apos;+@Where
EXEC sp_executesql @sql,N&apos;@PageCount int OUTPUT&apos;,@PageCount OUTPUT
SET @PageCount=(@PageCount+@PageSize-1)/@PageSize
END

--计算分页显示的TOPN值
DECLARE @TopN varchar(20),@TopN1 varchar(20)
SELECT @TopN=@PageSize,
@TopN1=(@PageCurrent-1)*@PageSize

--第一页直接显示
IF @PageCurrent=1
EXEC(N&apos;SELECT TOP &apos;+@TopN
+N&apos; &apos;+@FieldShow
+N&apos; FROM &apos;+@tbname
+N&apos; &apos;+@Where
+N&apos; &apos;+@FieldOrder)
ELSE
BEGIN
--处理别名
IF @FieldShow=N&apos;*&apos;
SET @FieldShow=N&apos;a.*&apos;

--生成主键(惟一键)处理条件
DECLARE @Where1 nvarchar(4000),@Where2 nvarchar(4000),
@s nvarchar(1000),@Field sysname
SELECT @Where1=N&apos;&apos;,@Where2=N&apos;&apos;,@s=@FieldKey
WHILE CHARINDEX(N&apos;,&apos;,@s)>0
SELECT @Field=LEFT(@s,CHARINDEX(N&apos;,&apos;,@s)-1),
@s=STUFF(@s,1,CHARINDEX(N&apos;,&apos;,@s),N&apos;&apos;),
@Where1=@Where1+N&apos; AND a.&apos;+@Field+N&apos;=b.&apos;+@Field,
@Where2=@Where2+N&apos; AND b.&apos;+@Field+N&apos; IS NULL&apos;,
@Where=REPLACE(@Where,@Field,N&apos;a.&apos;+@Field),
@FieldOrder=REPLACE(@FieldOrder,@Field,N&apos;a.&apos;+@Field),
@FieldShow=REPLACE(@FieldShow,@Field,N&apos;a.&apos;+@Field)
SELECT @Where=REPLACE(@Where,@s,N&apos;a.&apos;+@s),
@FieldOrder=REPLACE(@FieldOrder,@s,N&apos;a.&apos;+@s),
@FieldShow=REPLACE(@FieldShow,@s,N&apos;a.&apos;+@s),
@Where1=STUFF(@Where1+N&apos; AND a.&apos;+@s+N&apos;=b.&apos;+@s,1,5,N&apos;&apos;),
@Where2=CASE
WHEN @Where=&apos;&apos; THEN N&apos;WHERE (&apos;
ELSE @Where+N&apos; AND (&apos;
END+N&apos;b.&apos;+@s+N&apos; IS NULL&apos;+@Where2+N&apos;)&apos;

--执行查询
EXEC(N&apos;SELECT TOP &apos;+@TopN
+N&apos; &apos;+@FieldShow
+N&apos; FROM &apos;+@tbname
+N&apos; a LEFT JOIN(SELECT TOP &apos;+@TopN1
+N&apos; &apos;+@FieldKey
+N&apos; FROM &apos;+@tbname
+N&apos; a &apos;+@Where
+N&apos; &apos;+@FieldOrder
+N&apos;)b ON &apos;+@Where1
+N&apos; &apos;+@Where2
+N&apos; &apos;+@FieldOrder)
END
GO

应一个网友的要求,把几个分页存储过程贴上来,

来源:互联网

你可能感兴趣的:(sql,互联网,Go)