求一个高效的存储过程(ms 2000)
要支持复杂的查询条件以及支持多字段任意排序

解决方案 »

  1.   

    有关分页参考: 
    SQL code--TOP n 实现的通用分页存储过程(转自邹建)
    CREATE PROC sp_PageView
    @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
    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
        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)
    ENDSQL code--使用系统存储过程实现的通用分页存储过程(转自邹建)
    CREATE PROC sp_PageView   
    @sql         ntext,     --要执行的sql语句
    @PageCurrent int=1,     --要显示的页码
    @PageSize    int=10,    --每页的大小
    @PageCount   int OUTPUT --总页数
    AS
    SET NOCOUNT ON
    DECLARE @p1 int
    --初始化分页游标
    EXEC sp_cursoropen 
        @cursor=@p1 OUTPUT,
        @stmt=@sql,
        @scrollopt=1,
        @ccopt=1,
        @rowcount=@PageCount OUTPUT--计算总页数
    IF ISNULL(@PageSize,0)<1 
        SET @PageSize=10
    SET @PageCount=(@PageCount+@PageSize-1)/@PageSize
    IF ISNULL(@PageCurrent,0)<1 OR ISNULL(@PageCurrent,0)>@PageCount
        SET @PageCurrent=1
    ELSE
        SET @PageCurrent=(@PageCurrent-1)*@PageSize+1--显示指定页的数据
    EXEC sp_cursorfetch @p1,16,@PageCurrent,@PageSize--关闭分页游标
    EXEC sp_cursorclose @p1
    原作,爱新觉罗
      

  2.   

    http://www.cnblogs.com/slightboy/archive/2005/09/02/228874.html
      

  3.   

    以前总结的
    http://blog.csdn.net/Fibona/archive/2007/03/02/1519480.aspx
      

  4.   

    参考
    http://www.cnblogs.com/Jamedy/archive/2007/04/08/320738.html
    http://www.cnblogs.com/sleeping/archive/2008/07/08/509556.html
    http://www.cnblogs.com/freeliver54/archive/2006/12/31/608858.html
    http://www.cnblogs.com/virusswb/archive/2008/01/23/1049605.html
      

  5.   

    http://topic.csdn.net/u/20081224/21/24a00c1d-bd71-4588-b5a8-93b5bed7767f.html
    这个我昨天刚看到的  不错
      

  6.   

    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[Pro_Activities_GetPaged]
    (
    @WhereClause varchar (4000)  , @OrderBy varchar (4000)  , @PageIndex int   , @PageSize int ,

    @total int output
    )
    AS
    BEGIN
    DECLARE @PageLowerBound int
    DECLARE @PageUpperBound int

    -- Set the page bounds
    SET @PageLowerBound = @PageSize * @PageIndex
    SET @PageUpperBound = @PageLowerBound + @PageSize IF (@OrderBy is null or LEN(@OrderBy) < 1)
    BEGIN
    -- default order by to first column
    SET @OrderBy = 'Activity_ID'
    END
    -- SQL Server 2005 Paging
    DECLARE @SQL as nvarchar(4000)
    SET @SQL = 'WITH PageIndex AS ('
    SET @SQL = @SQL + ' SELECT'
    IF @PageSize > 0
    BEGIN
    SET @SQL = @SQL + ' TOP ' + convert(nvarchar, @PageUpperBound)
    END
    SET @SQL = @SQL + ' ROW_NUMBER() OVER(ORDER BY ' + @OrderBy + ') as RowIndex'
    SET @SQL = @SQL + ', A.Activity_ID'
    SET @SQL = @SQL + ', A.Start_Date'
    SET @SQL = @SQL + ', C.Company_Name'
    SET @SQL = @SQL + ', A.Follow_Person'
    SET @SQL = @SQL + ', A.Contact_Name'
    SET @SQL = @SQL + ', A.Regardings'
    SET @SQL = @SQL + ', A.Activity_type'
    SET @SQL = @SQL + ', A.Phone'
    SET @SQL = @SQL + ', A.Duty'
    SET @SQL = @SQL + ', A.Details'
    SET @SQL = @SQL + ', A.postulate'
    SET @SQL = @SQL + ', A.Why'
    SET @SQL = @SQL + ', A.Proceeding'
    SET @SQL = @SQL + ', A.Result'
    SET @SQL = @SQL + ', A.Chance'
    SET @SQL = @SQL + ', A.Start_Time'
    SET @SQL = @SQL + ', A.End_Time'
    SET @SQL = @SQL + ', A.Ac_Duration_Hours'
    SET @SQL = @SQL + ', A.Comment'
    SET @SQL = @SQL + ', A.Creator'
    SET @SQL = @SQL + ', A.DeptName'
    SET @SQL = @SQL + ', A.IsPublic'
    SET @SQL = @SQL + ', A.Banshichu'
    SET @SQL = @SQL + ', A.QuDao'
    SET @SQL = @SQL + ' FROM ActivitiesLog A 
    left join Companys C on A.Company_ID = C.Company_ID' IF LEN(@WhereClause) > 0
    BEGIN
    SET @SQL = @SQL + ' WHERE ' + @WhereClause
    END
    SET @SQL = @SQL + ' ) SELECT'
    SET @SQL = @SQL + ' Activity_ID'
    SET @SQL = @SQL + ', Start_Date'
    SET @SQL = @SQL + ', Company_Name'
    SET @SQL = @SQL + ', Follow_Person'
    SET @SQL = @SQL + ', Contact_Name'
    SET @SQL = @SQL + ', Regardings'
    SET @SQL = @SQL + ', Activity_Type'
    SET @SQL = @SQL + ', Phone'
    SET @SQL = @SQL + ', Duty'
    SET @SQL = @SQL + ', Details'
    SET @SQL = @SQL + ', Postulate'
    SET @SQL = @SQL + ', Why'
    SET @SQL = @SQL + ', Proceeding'
    SET @SQL = @SQL + ', Result'
    SET @SQL = @SQL + ', Chance'
    SET @SQL = @SQL + ', Start_Time'
    SET @SQL = @SQL + ', End_Time'
    SET @SQL = @SQL + ', Ac_Duration_Hours'
    SET @SQL = @SQL + ', Comment'
    SET @SQL = @SQL + ', Creator'
    SET @SQL = @SQL + ', DeptName'
    SET @SQL = @SQL + ', IsPublic'
    SET @SQL = @SQL + ', Banshichu'
    SET @SQL = @SQL + ', QuDao'
    SET @SQL = @SQL + ' FROM PageIndex'
    SET @SQL = @SQL + ' WHERE RowIndex > ' + convert(nvarchar, @PageLowerBound)
    IF @PageSize > 0
    BEGIN
    SET @SQL = @SQL + ' AND RowIndex <= ' + convert(nvarchar, @PageUpperBound)
    END
    SET @SQL = @SQL + ' ORDER BY ' + @OrderBy
    EXEC sp_executesql @SQL -- get row count
    SET @SQL = 'SELECT @a=COUNT(1)'
    SET @SQL = @SQL + ' FROM ActivitiesLog A 
    left join Companys C on A.Company_ID = C.Company_ID'
    IF LEN(@WhereClause) > 0
    BEGIN
    SET @SQL = @SQL + ' WHERE ' + @WhereClause
    END
    EXEC sp_executesql @SQL,N'@a int output',@total output
    END