问题很清楚,购买商品产生订单,订单下面有多个商品,有个页面显示订单列表,我希望在显示订单列表的时候,在每一条订单下方相应显示出哪些商品,数据表设计初步想一个订单表,一个订单商品表,这样的一个主从式的表设计。但是在显示订单列表的时候,在兼顾到性能方面,如何做这样一个查询,分页显示订单,请各位帮帮新人,谢谢。最后的效果类似淘宝的“已买到宝贝”页面的效果!

解决方案 »

  1.   

    SET   QUOTED_IDENTIFIER   ON     
      GO   
      SET   ANSI_NULLS   ON     
      GO   
        
      /*--用存储过程实现的分页程序   
        
        显示指定表、视图、查询结果的第X页   
        对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法   
        如果视图或查询结果中有主键,不推荐此方法   
        
      --邹建   2003.09(引用请保留此信息)--*/   
        
      /*--调用示例   
        exec   p_show   '地区资料'   
        
        exec   p_show   '地区资料',5,3,'地区编号,地区名称,助记码','地区编号'   
      --*/   
      ALTER     Proc   UP_Show   
      @QueryStr   nvarchar(4000),   --表名、视图名、查询语句   
      @PageSize   int=10,       --每页的大小(行数)   
      @PageCurrent   int=1,       --要显示的页   
      @FdShow   nvarchar   (4000)='',   --要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段   
      @FdOrder   nvarchar   (1000)='',   --排序字段列表   
      @Rows   int   =   null   OUTPUT             --   输出记录数,   如果@rows为null,   则输出记录数,   否则不要输出   
      as   
      set   nocount   on   
      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,'')   when   ''   then   '   *'   else   '   '+@FdShow   end   
        ,@FdOrder=case   isnull(@FdOrder,'')   when   ''   then   ''   else   '   order   by   '+@FdOrder   end   
        ,@QueryStr=case   when   @Obj_ID   is   not   null   then   '   '+@QueryStr   else   '   ('+@QueryStr+')   a'   end   
        
      --如果显示第一页,可以直接用top来完成   
      if   @PageCurrent=1     
      begin   
        select   @Id1=cast(@PageSize   as   varchar(20))   
        exec('select   top   '+@Id1+@FdShow+'   from   '+@QueryStr+@FdOrder)   
        return   
      end   
        
      --如果是表,则检查表中是否有标识更或主键   
      if   @Obj_ID   is   not   null   and   objectproperty(@Obj_ID,'IsTable')=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='PK')   
            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='PK'   and   parent_obj=@Obj_ID   
            )))   
          if   @@rowcount>1     --检查表中的主键是否为复合主键   
          begin   
            select   @strfd='',@strjoin='',@strwhere=''   
            select   @strfd=@strfd+',['+name+']'   
              ,@strjoin=@strjoin+'   and   a.['+name+']=b.['+name+']'   
              ,@strwhere=@strwhere+'   and   b.['+name+']   is   null'   
              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='PK'   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:     
      if   @Rows   is   null   
      begin   
      declare   @lbuseidentity   nvarchar(1000)   
      set   @lbuseidentity   =   'select   @rows   =   count(*)   from   '+@QueryStr   
      exec   sp_executesql   @lbuseidentity,   N'@Rows   int   out',   @Rows   out   
      end   
        exec('select   top   '+@Id1+@FdShow+'   from   '+@QueryStr   
          +'   where   '+@FdName+'   not   in(select   top   '   
          +@Id2+'   '+@FdName+'   from   '+@QueryStr+@FdOrder   
          +')'+@FdOrder   
          )   
        return   
        
      /*--表中有复合主键的处理方法--*/   
      lbusepk:       
      if   @Rows   is   null   
      begin   
      declare   @lbusepk   nvarchar(1000)   
      set   @lbusepk   =   'select   @rows   =   count(*)   from   '+@QueryStr   
      exec   sp_executesql   @lbusepk,   N'@Rows   int   out',   @Rows   out   
      end   
        
        exec('select   '+@FdShow+'   from(select   top   '+@Id1+'   a.*   from   
          (select   top   100   percent   *   from   '+@QueryStr+@FdOrder+')   a   
          left   join   (select   top   '+@Id2+'   '+@strfd+'     
          from   '+@QueryStr+@FdOrder+')   b   on   '+@strjoin+'   
          where   '+@strwhere+')   a'   
          )   
        return   
        
      /*--用临时表处理的方法--*/   
      lbusetemp:       
      select   @FdName='[ID_'+cast(newid()   as   varchar(40))+']'   
        ,@Id1=cast(@PageSize*(@PageCurrent-1)   as   varchar(20))   
        ,@Id2=cast(@PageSize*@PageCurrent-1   as   varchar(20))   
        
      declare   @lbusetemp   nvarchar(4000)   
      set   @lbusetemp   =   'select   '+@FdName+'=identity(int,0,1),'+@FdShow+'   
          into   #tb   from'+@QueryStr+@FdOrder   
      +case   when   @Rows   is   null   then   '   set   @Rows   =   @@rowcount   '   else   ''   end   +   '   
        select   '+@FdShow+'   from   #tb   where   '+@FdName+'   between   '   
        +@Id1+'   and   '+@Id2   
        exec   sp_executesql   @lbusetemp,     N'@Rows   int   out',   @Rows   out   
      GO   
      SET   QUOTED_IDENTIFIER   OFF     
      GO   
      SET   ANSI_NULLS   ON     
      GO   
      

  2.   

    lz:你的需求是这样吗?订单
    201204160001
    201204160002
    201204160003
    ...订单商品
    201204160001    a001
    201204160001    a002
    201204160001    a003订单商品是变化的,它的变化取决于光标所点的主订单号,比如上面的如果光标点的是第二个订单号,那么订单商品明细则显示的是第二个订单的商品。我们公司的ERP里面就有这个的。你所说的分页是主订单分页,还是商品分页,其实这2个用的都是前面说过的分页存储过程,用分页的过程就行了。如果你想要的是
    订单号1
    明细
    订单号2
    明细
    ...
    那么这样的话就麻烦一点啦,也是像上面说的那样,需要做成循环的。如果这样再分页的话就要临时表存储起来所有的行,然后再分页。希望楼主成功。