SQL2000分页存储过程,针对表,2005有自带的row_number

注:INSERT INTO SELECT 在已有identity列时会报错,以下存储过程直接读取结构,所以不会

CREATE   PROCEDURE  TablePage
(
    
@TableName      nvarchar ( 255 ),         -- 表名
     @OrderStr      nvarchar ( 500 ),         -- 排序字段
     @PageNumber      int ,                 -- 当前页
     @PageSize      int                      -- 每页记录数
)
AS
DECLARE   @sqlstr          nvarchar ( 4000 )
DECLARE   @sqlins          nvarchar ( 1500 )     -- 导入数据至临时表时用SQL
DECLARE   @sqljoin      nvarchar ( 2000 )     -- 连接显示数据用SQL
DECLARE   @sqlpage      nvarchar ( 200 )     -- 分页计算
DECLARE   @TableId      int                  -- 表ID
DECLARE   @IndexId      int                  -- 主键约束ID
DECLARE   @RowCount      int                  -- 表中数据条数
DECLARE   @BegNumber      int                  -- 起始记录
DECLARE   @EndNumber      int                  -- 截止记录
DECLARE   @MaxPage      int                  -- 最大页

DECLARE   @KeyName     sysname             -- 主键字段名
DECLARE   @KeyType     sysname             -- 主键字段类型
DECLARE   @KeyPrec      smallint          -- 主键栏位为变长时长度
DECLARE   @KeyScale      tinyint              -- 主键栏位精度

IF   @PageNumber <= 0
    
SET   @PageNumber = 1
IF   @PageSize <= 0
    
SET   @PageSize = 1

SET   @TableId   =   OBJECT_ID ( @TableName )
IF   @TableId   IS   NULL
BEGIN
    
RAISERROR ( ' 表名或对象名不存在当前数据库中,请检查 ' 16 1 )
    
RETURN
END

-- 取得总记录数
SET   @sqlstr = ' SELECT @iRowCount=COUNT(*) FROM  ' + @TableName
EXEC  SP_EXECUTESQL  @sqlstr , N ' @iRowCount int OUTPUT ' @RowCount  OUTPUT

-- 取得主键
DECLARE  cur  CURSOR  STATIC  FOR
    
SELECT     C.name KeyName, T.name KeyType, C.prec, C.scale
    
FROM     syscolumns C
    
LEFT   JOIN  sysindexes I  ON  I.id = C.id
    
LEFT   JOIN  systypes T  ON  T.xtype = C.xtype
    
WHERE     C.id = @TableId
        
AND  (I.status  &   0x800 ) = 0x800
        
AND  (
            C.name
= index_col ( @TableName , I.indid,  1 OR  C.name = index_col ( @TableName , I.indid,  2 OR
            C.name
= index_col ( @TableName , I.indid,  3 OR  C.name = index_col ( @TableName , I.indid,  4 OR
            C.name
= index_col ( @TableName , I.indid,  5 OR  C.name = index_col ( @TableName , I.indid,  6 OR
            C.name
= index_col ( @TableName , I.indid,  7 OR  C.name = index_col ( @TableName , I.indid,  8 OR
               C.name
= index_col ( @TableName , I.indid,  9 OR  C.name = index_col ( @TableName , I.indid,  10 OR
            C.name
= index_col ( @TableName , I.indid,  11 OR  C.name = index_col ( @TableName , I.indid,  12 OR
            C.name
= index_col ( @TableName , I.indid,  13 OR  C.name = index_col ( @TableName , I.indid,  14 OR
            C.name
= index_col ( @TableName , I.indid,  15 OR  C.name = index_col ( @TableName , I.indid,  16 )
        )
OPEN  cur
IF   @@CURSOR_ROWS <= 0
BEGIN
    
RAISERROR ( ' 指定表中不存在主键,请检查 ' 16 1 )
    
RETURN
END
-- 存在主键,创建同样主键临时表
FETCH   next   FROM  cur  INTO   @KeyName @KeyType @KeyPrec @KeyScale
SET   @sqlstr = ' CREATE TABLE #TMP(ROW_NUMBER INT IDENTITY(1, 1) '
SET   @sqlins = ''
SET   @sqljoin = ''
WHILE @@FETCH_STATUS = 0  )
BEGIN
    
-- 插入SQL
     IF   @sqlins <> ''
        
SET   @sqlins = @sqlins + ' , '
    
SET   @sqlins = @sqlins + @KeyName
    
    
-- 连接SQL
     IF   @sqljoin <> ''
        
SET   @sqljoin = @sqljoin + '  AND #TMP. ' + @KeyName + ' = ' + @TableName + ' . ' + @KeyName
    
ELSE
        
SET   @sqljoin = @sqljoin + '  LEFT JOIN  ' + @TableName + '  ON #TMP. ' + @KeyName + ' = ' + @TableName + ' . ' + @KeyName
    
SET   @sqlstr = @sqlstr + ' , ' + @KeyName + '   ' + @KeyType

    
-- 定义主键类型及长度
     IF   @KeyType = ' binary '   OR   @KeyType = ' char '   OR   @KeyType = ' nchar '   OR   @KeyType = ' nvarchar '  
        
OR   @KeyType = ' varbinary '   OR   @KeyType = ' varchar '
    
BEGIN
        
-- 类型是可变长度,无精度时,取prec栏位
         -- 不定长,无精度的包括: binary(173), char(175), nchar(239),nvarchar(231), varbinary(165), varchar(167)
         SET   @sqlstr = @sqlstr + ' ( ' + CAST ( @KeyPrec   AS   nvarchar ) + ' ) '
    
END
    
ELSE   IF   @KeyType = ' decimal '   OR   @KeyType = ' numeric '
    
BEGIN
        
-- 类型是可变长度且拥有精度时,取prec栏位+','+scale栏位
         -- 不定长,有精度的包括: decimal(106), numeric(108)
         SET   @sqlstr = @sqlstr + ' ( ' + CAST ( @KeyPrec   AS   nvarchar ) + ' , ' + CAST ( @KeyScale   AS   nvarchar ) + ' ) '
    
END
    
-- 其它类型是定长类型时,无须指定长度

    
FETCH   next   FROM  cur  INTO   @KeyName @KeyType @KeyPrec @KeyScale
END
CLOSE  cur
DEALLOCATE  cur
SET   @sqlstr = @sqlstr + ' ) '

-- 插入SQL
SET   @sqlins = ' INSERT INTO #TMP( ' + @sqlins + ' ) SELECT  ' + @sqlins + '  FROM  ' + @TableName

-- 计算页面
SET   @MaxPage = CAST ( @RowCount / @PageSize   AS   INT )
IF   @RowCount % @PageSize > 0
    
SET   @MaxPage = @MaxPage + 1
IF   @MaxPage = 0
    
SET   @MaxPage = 1
IF   @PageNumber > @MaxPage
    
SET   @PageNumber = @MaxPage

SET   @BegNumber = ( @PageNumber - 1 ) * @PageSize + 1
SET   @EndNumber = @PageNumber * @PageSize
SET   @sqlpage = '  WHERE #TMP.ROW_NUMBER BETWEEN  ' + CAST ( @BegNumber   AS   nvarchar ) + '  AND  ' + CAST ( @EndNumber   AS   nvarchar )

-- 连接SQL
SET   @sqljoin = ' SELECT #TMP.ROW_NUMBER, ' + @TableName + ' .* FROM #TMP  ' + @sqljoin

-- 整合SQL
SET   @sqlstr = @sqlstr + '   ' + @sqlins + '   ' + @sqljoin + @sqlpage

-- 加上删除命令
SET   @sqlstr = @sqlstr + '  DROP TABLE #TMP '
EXEC ( @sqlstr )

--TablePage 'TableName','',39,17 

你可能感兴趣的:(row_number)