真正的分页存储过程,借鉴了CSDN上众多力量,除BUG版


  前段时间研究分页的时候,在CSDN的BLOG上看到了一位兄弟写的分页存储过程,发现非常好,于是,就使用了这个存储过程,下面是原版的分页存储过程   
    
  

-- 开始   
   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     !=     ''    
          
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     !=     ''    
                  
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    
  
-- 结束   

    
  当我在用这个存储过程的时候,刚开始没有发现问题,后来当我的条件很复杂的时候,发现,此存储过程执行遇到错误,下面是出现问题的条件  
  id<>0   and   (companyenname   like   '%shenzhen%'   or   companychname   like   '%shenzhen%'   or   web   like   '%shenzhen%'   or   memo   like   '%shenzhen%'     or   address   like   '%shenzhen%')     order   by   [id]   desc)   as   tblTmp)   and   id<>0   and   (companyenname   like   '%shenzhen%'   or   companychname   like   '%shenzhen%'   or   web   like   '%shenzhen%'   or   memo   like   '%shenzhen%'     or   address   like   '%shenzhen%')   and   salesid=9  
  照说这个条件是没有问题的,可是,用上面的存储过程执行,却老是报告错误  
  后来,经调试,输出生成后的SQL语句,发现,原来问题是出现在嵌套的SQL语句中使用的()身上,于是,我把存储过程改为下面的效果,终于排除了BUG,下面的存储过程不管你的条件有多复杂,只要格式正确,就能运行  
  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   !=   ''  
          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   !=   ''  
                  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  
   
  要注意看,修改后的存储过程在使用@strWhere时,都在其前后加上了(),这样,就防止嵌套的()出现错误  
   
  下面的代码是引用该存储过程的一个范例    
   
  SqlConnection   MyConnection=new   SqlConnection(ConfigurationSettings.AppSettings["dsn"]);  
  DataSet   MyDataSet=new   DataSet();   


  string   strKeyword
= Keyword. Text .Trim(). Replace (" ' "," ' ' ");   
  string   strSalesId=Sales.SelectedItem.Value;   
  int   RecordCount=CalcRecordCount();   
  RecordNumber.Text=RecordCount.ToString();   
  LblRecordNumber.Text=RecordCount.ToString();   
  string   strExpress="Id<>0";   
  if   (strKeyword!="")   
  strExpress=strExpress+"   and   (companyenname   like   
' % " + strKeyword + " % '    or   companychname   like    ' % " + strKeyword + " % '    or   Companyshortname   like    ' % " + strKeyword + " % '    or   web   like    ' % " + strKeyword + " % '    or   mainproduct   like    ' % " + strKeyword + " % '    or   phone   like    ' % " + strKeyword + " % '    or   memo   like    ' % " + strKeyword + " % '    or   address   like    ' % " + strKeyword + " % '    or   linkmanphone   like    ' % " + strKeyword + " % ' )";   
  if   (strSalesId!="")   
  strExpress=strExpress+"   and   salesid="+strSalesId;   
  SqlCommand   MyCommand=new   SqlCommand();   
  MyCommand.Connection=MyConnection;   
  MyCommand.CommandText="GetRecordFromPage";   
  MyCommand.CommandType=CommandType.StoredProcedure;   
  MyCommand.Parameters.Add("@tblName","customerview");   
  MyCommand.Parameters.Add("@fldName","id");   
  MyCommand.Parameters.Add("@strWhere",strExpress);   
  MyCommand.Parameters.Add("@PageSize",Int32.Parse(CustomerList.PageSize.ToString()));   
  MyCommand.Parameters.Add("@PageIndex",Int32.Parse(ViewState["PageIndex"].ToString())+1);   
  SqlDataReader   MyReader;   
  MyConnection.Open();   
  MyReader=MyCommand.ExecuteReader();   
  CustomerList.VirtualItemCount=RecordCount;   
  CustomerList.DataSource=MyReader;   
  CustomerList.DataKeyField="id";   
  CustomerList.DataBind();   
  MyReader.Close();   
  MyConnection.Close();   
    
  在这里,要注意的是存储过程使用的PAGEINDEX变量是从1开始 

最后,再排除一个BUG   
  将存储过程中   
  declare     @strSQL       varchar(1000)           --   主语句   
  declare   @strTmp       varchar(300)           --   临时变量   
  declare   @strOrder   varchar(400)               --   排序类型   
  改为   
  declare     @strSQL       varchar(2000)           --   主语句   
  declare   @strTmp       varchar(1000)           --   临时变量   
  declare   @strOrder   varchar(1000)               --   排序类型   
    

  因为我在调试中发现有些查询用的语句选不止300  
  最后,只要将以上存储过程代码复制并加入到你的数据库中,再按照范例来调用即可了 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值