zoukankan      html  css  js  c++  java
  • 转支持非主键排序的SQL存储过程

    CREATE PROCEDURE pagination
        @tbName      nvarchar(255) , -- 表名(允许多张表的join)
        @keyorder      nvarchar(255) , -- 用于排序的字段名 后面可以追加' asc' 或' desc', 不支持对多个字段排序
        @keymain      nvarchar(255), -- 主键字段名(如果用于排序的字段的值是唯一的,应将此参数设为''或null(不这样将会降低效率); 如果用于排序的字段的值不是唯一的, 则需要写真实的主键) 后面可以追加' asc' 或' desc', 不支持多个主键
        @columns nvarchar(1000)='*', -- 要选择的列 (注意: 本存储过程不会自动给列名或表名加方括号)
        @strWhere     nvarchar(3000) = '',  -- 查询条件 (注意: 不要加 where)
        @PageSize     int = 10, -- 页尺寸
        @PageIndex    int = 1 output, -- 页码
        @RowsCount    int=0 output, -- 记录总数,
        @PageCount int=0 output --页面总数
    AS
    begin

    declare @s1 nvarchar(100) -- 临时变量
    declare @s2 nvarchar(100) -- 临时变量

    declare @strSQL   nvarchar(4000) -- 主语句
    declare @strTmp   nvarchar(3000) -- 临时变量
    declare @strOrder nvarchar(2000) -- 排序类型

    --取得总行数
    if @strWhere != ''
     set @strSQL='SELECT @RowsCount=count(*) FROM '+@tbName+' where ' + @strWhere
    else
     set @strSQL='SELECT @RowsCount=count(*) FROM '+@tbName
    exec sp_executesql @strSQL, N'@RowsCount int out', @RowsCount out
    set @strSQL=''

    --计算总页数  
    set @PageCount=@RowsCount/@PageSize
    if (@RowsCount % @PageSize<>0)
     set @PageCount=@PageCount+1
    if (@PageCount<1)
     set @PageCount=1

    --错误处理
    if (@PageSize<1)
     set @PageSize=1
    if (@PageIndex<1)
     set @PageIndex=1
    if (@PageIndex>@PageCount)
     set @PageIndex=@PageCount

    --拼接Order By子句
    declare @strOrderType1 nvarchar(50)
    declare @strOrderType2 nvarchar(50)
    if(CHARINDEX(' desc', @keyorder)>0)
     begin
     set @strOrderType1='desc'
     set @keyorder=REPLACE(@keyorder, ' desc', '')
     end
    else
     begin
     set @strOrderType1='asc'
     set @keyorder=REPLACE(@keyorder, ' asc', '')
     end

    ----求字段类型start
    declare @OrderTable nvarchar(255)
    declare @OrderName nvarchar(255)
    declare @OrderType varchar(255)
    declare @OrderPrec varchar(50)
    declare @OrderDot int
    set @OrderDot=CHARINDEX('.', @keyorder)
    IF @OrderDot > 0
     BEGIN
     SET @OrderTable = SUBSTRING(@keyorder, 0, @OrderDot)
     SET @OrderName = SUBSTRING(@keyorder, @OrderDot + 1, LEN(@keyorder))
     END
    ELSE
     BEGIN
     SET @OrderTable = @tbName
     SET @OrderName = @keyorder
     END
    set @s1=REPLACE(REPLACE (@OrderTable,'[',''),']','')
    set @s2=REPLACE(REPLACE (@OrderName,'[',''),']','')
    SELECT @OrderType=t.[name], @OrderPrec=c.prec
    FROM sysobjects o
    JOIN syscolumns c on o.id=c.id
    JOIN systypes t on c.xusertype=t.xusertype
    WHERE o.name = @s1 AND c.[name] = @s2
    IF CHARINDEX('char', @OrderType) > 0
     SET @OrderType = @OrderType + '(' + CAST(@OrderPrec AS varchar) + ')'
    ----求字段类型end

    if @strOrderType1='asc'
     begin
     set @strOrderType1 = '>'
     set @strOrder = ' order by ' + @keyorder +' asc'
     end
    else
     begin
     set @strOrderType1 = '<'
     set @strOrder = ' order by ' + @keyorder +' desc'
     end
    if @keymain is null
     set @keymain=''
    if @keymain<>''
     begin
     if(CHARINDEX(' desc', @keymain)>0)
      begin
      set @strOrderType2='desc'
      set @keymain=REPLACE(@keymain, ' desc', '')
      end
     else
      begin
      set @strOrderType2='asc'
      set @keymain=REPLACE(@keymain, ' asc', '')
      end
     
     ----求字段类型start
     declare @MainTable nvarchar(255)
     declare @MainName nvarchar(255)
     declare @MainType varchar(255)
     declare @MainPrec varchar(50)
     declare @MainDot int
     set @MainDot=CHARINDEX('.', @keymain)
     IF @MainDot > 0
      BEGIN
      SET @MainTable = SUBSTRING(@keymain, 0, @MainDot)
      SET @MainName = SUBSTRING(@keymain, @MainDot + 1, LEN(@keymain))
      END
     ELSE
      BEGIN
      SET @MainTable = @tbName
      SET @MainName = @keymain
      END
     set @s1=REPLACE(REPLACE (@MainTable,'[',''),']','')
     set @s2=REPLACE(REPLACE (@MainName,'[',''),']','')
     SELECT @MainType=t.name, @MainPrec=c.prec
     FROM sysobjects o
     JOIN syscolumns c on o.id=c.id
     JOIN systypes t on c.xusertype=t.xusertype
     WHERE o.name = @s1 AND c.name = @s2

     IF CHARINDEX('char', @MainType) > 0
     SET @MainType = @MainType + '(' + CAST(@MainPrec AS varchar) + ')'
     ----求字段类型end
     
      if @strOrderType2='asc'
      begin
      set @strOrderType2='>'
      set @strOrder =@strOrder + ', ' + @keymain +' asc'
      end
      else
      begin
      set @strOrderType2='<'
      set @strOrder =@strOrder + ', ' + @keymain +' desc'
      end
     end

    --拼接查询语句
    if @PageIndex = 1
     begin
      set @strTmp =''
      if @strWhere != ''
      set @strTmp = ' where ' + @strWhere
      set @strSQL = 'select top ' + convert(nvarchar(100),@PageSize) + ' '+@columns+' from '   + @tbName + ' ' + @strTmp + ' ' + @strOrder
     end
    else
     begin
      --求临界值
      set @strSQL='declare @midData '+@OrderType+';'
      if @MainType is not null
      set @strSQL=@strSQL+'declare @midID '+@MainType+';'
      set @strSQL=@strSQL+'SET ROWCOUNT '+ convert(nvarchar(100),(@PageIndex-1)*@PageSize)+';'        
      if  @keymain<>''
      set @strSQL =@strSQL+ 'select @midData= '    + @keyorder + ', @midID=' + @keymain + ' from ' + @tbName
      else
      set @strSQL =@strSQL+ 'select @midData= '    + @keyorder + ' from ' + @tbName
      if @strWhere != ''
      set @strSQL=@strSQL+ ' where ' + @strWhere
      set @strSQL=@strSQL+' '+@strOrder+';'
      --print (@strSQL); return
      --最终查询语句
      set @strSQL=@strSQL+'SET ROWCOUNT '+ convert(nvarchar(100),@PageSize) +';'        
      if  @keymain<>''
      set @strSQL =@strSQL+ 'select '+@columns+' from '    + @tbName + ' where (' + @keyorder + @strOrderType1 + '@midData or ('    + @keyorder + '=@midData and ' + @keymain + @strOrderType2 +'@midID))'
      else
      set @strSQL =@strSQL+ 'select '+@columns+' from '    + @tbName + ' where ' + @keyorder + @strOrderType1 + '@midData'
      if @strWhere <> ''
      set @strSQL=@strSQL+' and '+ @strWhere
      set @strSQL=@strSQL+' ' + @strOrder
     end

    --执行查询语句
    --print (@strSQL); return
    exec (@strSQL)

    end
    GO

  • 相关阅读:
    Export excel的终级解决方案
    Power Designer 常见问题
    正反向数据库及生成设计报告
    寻求最佳开发模式,免得落得“精”尽人亡
    XmlNode与XmlElement的区别总结
    软件版本的定义:
    我发现博客园一个很严重的问题
    sql 行转列的终极写法
    js 自定义 $ 选择器
    可持续集成环境相关文章
  • 原文地址:https://www.cnblogs.com/ourwap/p/1487085.html
Copyright © 2011-2022 走看看