+ -
当前位置:首页 → 问答吧 → sql分页语句。

sql分页语句。

时间:2007-04-02

来源:互联网

eg:   id(主键,自动编号)   name,   class
让每页显示10条记录,如何写sql。谢谢了

作者: kiss_nb   发布时间: 2007-04-02

SET   QUOTED_IDENTIFIER   ON  
GO
SET   ANSI_NULLS   ON  
GO

create     PROC   SP_pagination2
(
@sqlstr       nvarchar(4000),   --查询字符串
@pagecount       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   @rowcount   as   总行数,ceiling(1.0*@rowcount/@pagesize)   as   页数,@pagecount   as   当前页      
set   @pagecount=(@pagecount-1)*@pagesize+1      
exec   sp_cursorfetch   @P1,16,@pagecount,@pagesize          
exec   sp_cursorclose   @P1

GO
SET   QUOTED_IDENTIFIER   OFF  
GO
SET   ANSI_NULLS   ON  
GO


---
用这个存储过程

作者: yahuu   发布时间: 2007-04-02

sp_cursoropen   ---请告知道这个是个什么存储过程!
起什么作用,我也看过这个存储过程,是老大的,但是就是不知道这个是什么东东!
谢谢

作者: mugua604   发布时间: 2007-04-02

这个不是老大的,这个好像是微软没有公开的东东

作者: yahuu   发布时间: 2007-04-02

这个PROC是老大该过的啊,但我不知道sp_cursoropen   的用发!

作者: mugua604   发布时间: 2007-04-02

邹老大的   TOP   n   实现的通用分页存储过程

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

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

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

--如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值)
IF   @PageCount   IS   NULL
BEGIN
DECLARE   @sql   nvarchar(4000)
SET   @sql=N 'SELECT   @PageCount=COUNT(*) '
+N '   FROM   '+@tbname
+N '   '+@Where
EXEC   sp_executesql   @sql,N '@PageCount   int   OUTPUT ',@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 'SELECT   TOP   '+@TopN
+N '   '+@FieldShow
+N '   FROM   '+@tbname
+N '   '+@Where
+N '   '+@FieldOrder)
ELSE
BEGIN
--处理别名
IF   @FieldShow=N '* '
SET   @FieldShow=N 'a.* '

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

--执行查询
EXEC(N 'SELECT   TOP   '+@TopN
+N '   '+@FieldShow
+N '   FROM   '+@tbname
+N '   a   LEFT   JOIN(SELECT   TOP   '+@TopN1
+N '   '+@FieldKey
+N '   FROM   '+@tbname
+N '   a   '+@Where
+N '   '+@FieldOrder
+N ')b   ON   '+@Where1
+N '   '+@Where2
+N '   '+@FieldOrder)
END
--===============================
邹老大的字符串缓存实现的通用分页存储过程

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

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

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

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

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

--第一页直接显示
IF   @PageCurrent=1
EXEC(N 'SELECT   TOP   '+@TopN
+N '   '+@FieldShow
+N '   FROM   '+@tbname
+N '   '+@Where
+N '   '+@FieldOrder)
ELSE
BEGIN
SELECT   @PageCurrent=@TopN1,
@sql=N 'SELECT   @n=@n-1,@s=CASE   WHEN   @n < '+@TopN
+N '   THEN   @s+N ' ', ' '+QUOTENAME(RTRIM(CAST( '+@FieldKey
+N '   as   varchar(8000))),N ' ' ' ' ' ' ' ')   ELSE   N ' ' ' '   END   FROM   '+@tbname
+N '   '+@Where
+N '   '+@FieldOrder
SET   ROWCOUNT   @PageCurrent
EXEC   sp_executesql   @sql,
N '@n   int,@s   nvarchar(4000)   OUTPUT ',
@PageCurrent,@sql   OUTPUT
SET   ROWCOUNT   0
IF   @sql=N ' '
EXEC(N 'SELECT   TOP   0 '
+N '   '+@FieldShow
+N '   FROM   '+@tbname)
ELSE
BEGIN
SET   @sql=STUFF(@sql,1,1,N ' ')
--执行查询
EXEC(N 'SELECT   TOP   '+@TopN
+N '   '+@FieldShow
+N '   FROM   '+@tbname
+N '   WHERE   '+@FieldKey
+N '   IN( '+@sql
+N ')   '+@FieldOrder)
END
END

----------------------------------------------------
邹老大的使用系统存储过程实现的通用分页存储过程

CREATE   PROC   sp_PageView      
@sql                   ntext,           --要执行的sql语句
@PageCurrent   int=1,           --要显示的页码
@PageSize         int=10,         --每页的大小
@PageCount       int   OUTPUT   --总页数
AS
SET   NOCOUNT   ON
DECLARE   @p1   int
--初始化分页游标
EXEC   sp_cursoropen  
@cursor=@p1   OUTPUT,
@stmt=@sql,
@scrollopt=1,
@ccopt=1,
@rowcount=@PageCount   OUTPUT

--计算总页数
IF   ISNULL(@PageSize,0) <1  
SET   @PageSize=10
SET   @PageCount=(@PageCount+@PageSize-1)/@PageSize
IF   ISNULL(@PageCurrent,0) <1   OR   ISNULL(@PageCurrent,0)> @PageCount
SET   @PageCurrent=1
ELSE
SET   @PageCurrent=(@PageCurrent-1)*@PageSize+1

--显示指定页的数据
EXEC   sp_cursorfetch   @p1,16,@PageCurrent,@PageSize

--关闭分页游标
EXEC   sp_cursorclose   @p1

作者: yahuu   发布时间: 2007-04-02

--邹老大的:


CREATE   PROCEDURE   pagination3
@tblName   varchar(255),   --   表名
@strGetFields   varchar(1000)   =   '* ',   --   需要返回的列
@fldName   varchar(255)= ' ',   --   排序的字段名
@PageSize   int   =   10,   --   页尺寸
@PageIndex   int   =   1,   --   页码
@doCount   bit   =   0,   --   返回记录总数,   非   0   值则返回
@OrderType   bit   =   0,   --   设置排序类型,   非   0   值则降序
@strWhere   varchar(1500)   =   ' ' ' '   --   查询条件   (注意:   不要加   where)
AS
declare   @strSQL   varchar(5000)   --   主语句
declare   @strTmp   varchar(110)   --   临时变量
declare   @strOrder   varchar(400)   --   排序类型
if   @doCount   !=   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   @OrderType   !=   0
begin
set   @strTmp   =   ' <(select   min '
set   @strOrder   =   '   order   by   [ '   +   @fldName   + ']   desc '--如果@OrderType不是0,就执行降序,这句很重要!

end
else
begin
set   @strTmp   =   '> (select   max '
set   @strOrder   =   '   order   by   [ '   +   @fldName   + ']   asc '
end
if   @PageIndex   =   1
begin
if   @strWhere   !=   ' ' ' '
set   @strSQL   =   'select   top   '   +   str(@PageSize)   + '   '+@strGetFields+   '
from   [ '   +   @tblName   +   ']   where   '   +   @strWhere   +   '   '   +   @strOrder
else
set   @strSQL   =   'select   top   '   +   str(@PageSize)   + '   '+@strGetFields+   '
from   [ '+   @tblName   +   ']   '+   @strOrder
--如果是第一页就执行以上代码,这样会加快执行速度

end
else
begin--以下代码赋予了@strSQL以真正执行的SQL代码 

set   @strSQL   =   'select   top   '   +   str(@PageSize)   + '   '+@strGetFields+   '   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)   + '   '+@strGetFields+   '   from   [ '
+   @tblName   +   ']   where   [ '   +   @fldName   +   '] '   +   @strTmp   +   '([ '
+   @fldName   +   '])   from   (select   top   '   +   str((@PageIndex-1)*@PageSize)   +   '   [ '
+   @fldName   +   ']   from   [ '   +   @tblName   +   ']   where   '   +   @strWhere   +   '   '
+   @strOrder   +   ')   as   tblTmp)   and   '   +   @strWhere   +   '   '   +   @strOrder
end
end
exec   (@strSQL)
GO

作者: ojuju10   发布时间: 2007-04-02

哎..,不会用

作者: kiss_nb   发布时间: 2007-04-02

如何不会用了?把我贴的第一个在你的数据库中执行,建立这个存储过程

要用的话就   exec   SP_pagination2   ( 'select   *   from   xxxx ',2,4)
意思是:要每页4行,第2页,   2   和   4   你可以自己修改

作者: yahuu   发布时间: 2007-04-02

为什么是存储过程 直接的Sql语句可以做分页吗 ? 比如在Access里面要做分页呢?

作者: ZiYi5662120   发布时间: 2011-12-14