对多个表,多字段,多条件,多排序条件查询后,将结果放在gridview里,
现对gridview分页,写了几个sql都不行,
请教存储过程的@sql怎么写?

解决方案 »

  1.   

    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    GO
    /*
    分页排序存储过程 V1.0
    */ALTER procedure [dbo].[sp_KeyPage]
    @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
    --检查对象是否有效
    IF OBJECT_ID(@tbname) IS NULL --OBJECT_ID 功能:返回数据库对象的标识号
    BEGIN
        RAISERROR(N'对象"%s"不存在',1,16,@tbname)
        RETURN
    END
    IF OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTable')=0 --OBJECTPROPERTY 功能:返回当前数据库中对象的有关信息。
        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这是我们老师帮我们写的万能分页存储过程
    你试看行不?
      

  2.   

    不是有个分页的类吗?
    PagedDataSource 没用过吗?
    在你的 load事件里
      ViewState["page"] = 0
      在调用此方法private void DataBind()
    {
      你的datasource = 获得他全部的数据的集合
       PagedDataSource dst = new  PagedDataSource();
       dst.AllowPageing = true;
       dst.PageSize = 5;
       dst.CurrentPageIndex =Pager;
        你的datasource = dst;
        你的datasource.databind();
    }
    这样就可以了
      

  3.   

    不是有个分页的类吗?
    PagedDataSource 没用过吗?
    在你的 load事件里
      ViewState["page"] = 0
      在调用此方法private void DataBind()
    {
      你的datasource = 获得他全部的数据的集合
       PagedDataSource dst = new  PagedDataSource();
       dst.AllowPageing = true;
       dst.PageSize = 5;
       dst.CurrentPageIndex =Pager;
        你的datasource = dst;
        你的datasource.databind();
    }
    这样就可以了
      

  4.   

    如果是不想用系统自带的分页
    http://topic.csdn.net/u/20090112/17/ba500246-26f8-4605-9a75-20d926c49bb3.html
    自己去找
      

  5.   

    CREATE   PROCEDURE   sp_page       @strTable       varchar(50),   --表名   
        @strColumn      varchar(50),   --按该列来进行分页   
        @intColType     int,           --@strColumn列的类型,0-数字类型,1-字符类型,2-日期时间类型   
        @intOrder       int,           --排序,0-顺序,1-倒序   
        @strColumnlist  varchar(800),  --要查询出的字段列表,*表示全部字段   
        @intPageSize    int,           --每页记录数   
        @intPageNum     int,           --指定页   
        @strWhere       varchar(800),  --查询条件   
        @intPageCount   int   OUTPUT   --总页数   
      AS    
    DECLARE   @sql    nvarchar(4000) --用于构造SQL语句
      DECLARE   @where1 varchar(800)   --构造条件语句
      DECLARE   @where2 varchar(800)   --构造条件语句
      IF   @strWhere   is   null   or   rtrim(@strWhere)=''   
      -- 为了避免SQL关键字与字段、表名等连在一起,首先为传入的变量添加空格
      BEGIN  --没有查询条件   
          SET   @where1=' WHERE '   
          SET   @where2=' '   
      END   
      ELSE   
      BEGIN  --有查询条件   
          SET   @where1=' WHERE  ('+@strWhere+')  AND  ' 
          SET   @where2=' WHERE  ('+@strWhere+')  '   
      END   
     set @strColumn = ' ' + @strColumn + ' '
      set @strColumnlist = ' ' + @strColumnlist + ' '
      --构造SQL语句,计算总页数。计算公式为 总页数 = Ceiling ( 记录个数 / 页大小 )  SET   @sql='SELECT   @intPageCount=CEILING((COUNT(*)+0.0)/'
            + CAST(@intPageSize   AS   varchar)
            + ')   FROM   ' + @strTable + @where2   
      --执行SQL语句,计算总页数,并将其放入@intPageCount变量中
      EXEC sp_executesql  @sql,N'@intPageCount   int   OUTPUT',@intPageCount   OUTPUT 
      --将总页数放到查询返回记录集的第一个字段前,此语句可省略
      --SET  @strColumnlist= Cast(@intPageCount as varchar(30)) + ' as PageCount,' + @strColumnlist     IF   @intOrder=0   --构造升序的SQL
          SET @sql='SELECT TOP '+ CAST(@intPageSize   AS   varchar)  + 
                   @strColumnlist +   
                   ' FROM ' + @strTable + @where1 + 
                   @strColumn + '>(SELECT MAX('+@strColumn+')  '+   
                   ' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1)  AS  varchar) +   
                   @strColumn + ' FROM '+ @strTable+@where2+' ORDER  BY '+@strColumn+')   t)  ORDER  BY '+ @strColumn +'asc '
      ELSE              --构造降序的SQL   
          SET @sql='SELECT TOP '+ CAST(@intPageSize   AS   varchar)  + 
                   @strColumnlist+   
                   ' FROM '+ @strTable + @where1 + 
                   @strColumn + '<(SELECT   MIN('+@strColumn+')   '+   
                   ' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1)  AS  varchar) +   
                   @strColumn + ' FROM '+ @strTable+@where2+' ORDER   BY '+@strColumn+'   DESC)   t)   ORDER   BY   '+   
                   @strColumn + ' DESC' 
      IF   @intPageNum=1--第一页   
          SET   @sql='SELECT   TOP   '+CAST(@intPageSize   AS   varchar) + @strColumnlist + ' FROM '+@strTable+   
                     @where2+' ORDER   BY   '+@strColumn+CASE   @intOrder WHEN  0 THEN  ''  ELSE  '  DESC'  
      END   
      --PRINT   @sql   
      EXEC(@sql)
    GO
      

  6.   

    http://topic.csdn.net/t/20051103/15/4369277.html
    http://www.jb51.net/article/17135.htm
    请参考一下
      

  7.   

    可以参考一下:http://blog.csdn.net/Fibona/archive/2007/03/02/1519480.aspx
      

  8.   

    hhxxcj写的我看明白了,但如果strColumn不是一列呢?
    就是  ,比如:字段1 asc,字段2 desc  排序条件是多列就不好使了  
      

  9.   

    C#:
        //分页
        protected void GridView1_OnPageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            //sqlcon是连接数据库的字符串
             //connnstring是在web.config里边配置好的
    <location allowOverride="true" inheritInChildApplications="true">
    <appSettings>
       <add key="CrystalImageCleaner-AutoStart" value="true" />
       <add key="CrystalImageCleaner-Sleep" value="60000" />
       <add key="CrystalImageCleaner-Age" value="120000" />
       <add key="connstring" value="uid=sa;password=123456;database=Persons;server=(local)" />  </appSettings>
    </location>
             //private SqlConnection sqlcon = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["connstring"]);
            string sqlstr = "select * from [Person]";
            sd = new SqlDataAdapter(sqlstr, sqlcon);
            DataSet ds = new DataSet();
            sqlcon.Open();
            sd.Fill(ds);        GridView1.PageIndex = e.NewPageIndex;
            GridView1.DataSource = ds;               //引用刚才建立的数据源
             sqlcon.Close();
            bind();
        }
    asp:
    GridView里边加上OnPageIndexChanging="GridView1_OnPageIndexChanging"  这个事件。
      

  10.   


    CREATE PROC [dbo].[SP_PageList]
    @tbname     sysname,           --要分页显示的表名
    @FieldKey   sysname,           --用于定位记录的主键(惟一键)字段,只能是单个字段
    @PageCurrent int=1,             --要显示的页码
    @PageSize   int=10,            --每页的大小(记录数)
    @FieldShow  nvarchar(1000)='',  --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段
    @FieldOrder  nvarchar(1000)='', --以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC
                                              --用于指定排序顺序
    @Where     nvarchar(1000)='',  --查询条件
    @RecordCount  int OUTPUT,       --总记录数
    @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 @RecordCount = @PageCount
    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
    多表的话,建立成视图,把视图名作为表名传进去
      

  11.   

    但是我觉得他们所说的传统的分页机制有问题,如:allowpaging=true, 再加上一个
      protected void GridView1_OnPageIndexChanging(object sender, GridViewPageEventArgs e) 
        { GridView1.PageIndex = e.NewPageIndex; 
            GridView1.DataSource = ds;              //引用刚才建立的数据源 
            sqlcon.Close(); 
            bind(); 
        } 
    asp: 
    GridView里边加上OnPageIndexChanging="GridView1_OnPageIndexChanging"  这个事件。
    函数,对于动态从后台数据库绑定的gridview 实现分页是行不通的,首先allowpaging="true"就不允许写的,