首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

分页存储过程 排除反复行

2013-09-24 
分页存储过程 排除重复行分页存储过程 因为使用ROW_NUMBER() 所以不能使用distinct去掉重复的行。请教如何

分页存储过程 排除重复行
分页存储过程 因为使用ROW_NUMBER() 所以不能使用distinct去掉重复的行。请教如何修改才能去掉重复的行
Create PROCEDURE [dbo].[GetRecordFromPage] 
    @SelectList            VARCHAR(2000),    --欲选择字段列表
    @TableSource        VARCHAR(100),    --表名或视图表 
    @SearchCondition    VARCHAR(2000),    --查询条件 
    @OrderExpression    VARCHAR(1000),    --排序表达式
    @PageIndex            INT = 1,        --页号,从0开始
    @PageSize            INT = 10        --页尺寸
AS 
BEGIN
    IF @SelectList IS NULL or LTRIM(RTRIM(@SelectList)) = ''
    BEGIN
        SET @SelectList = '*'
    END
    PRINT @SelectList

    SET @SearchCondition = ISNULL(@SearchCondition,'')
    SET @SearchCondition = LTRIM(RTRIM(@SearchCondition))
    IF @SearchCondition <> '' 
    BEGIN
        IF UPPER(SUBSTRING(@SearchCondition,1,5)) <> 'Where'
        BEGIN
            SET @SearchCondition = 'Where ' + @SearchCondition
        END
    END
    PRINT @SearchCondition

    SET @OrderExpression = ISNULL(@OrderExpression,'')
    SET @OrderExpression = LTRIM(RTRIM(@OrderExpression))
    IF @OrderExpression <> ''
    BEGIN
        IF UPPER(SUBSTRING(@OrderExpression,1,5)) <> 'Where'
        BEGIN
            SET @OrderExpression = 'ORDER BY ' + @OrderExpression 
        END
    END
    PRINT @OrderExpression


    IF @PageIndex IS NULL or @PageIndex < 1
    BEGIN
        SET @PageIndex = 1
    END
    PRINT @PageIndex
    IF @PageSize IS NULL or @PageSize < 1
    BEGIN
        SET @PageSize = 10
    END
    PRINT  @PageSize

    DECLARE @SqlQuery VARCHAR(4000)

    SET @SqlQuery='Select '+@SelectList+',RowNumber 
    FROM 
        (Select ' + @SelectList + ',ROW_NUMBER() OVER( '+ @OrderExpression +') AS RowNumber 
          FROM '+@TableSource+' '+ @SearchCondition +') AS RowNumberTableSource 
    Where RowNumber BETWEEN ' + CAST(((@PageIndex - 1)* @PageSize+1) AS VARCHAR) 
    + ' AND ' + 
    CAST((@PageIndex * @PageSize) AS VARCHAR) 
--    orDER BY ' + @OrderExpression
    PRINT @SqlQuery
    SET NOCOUNT ON
    EXECUTE(@SqlQuery)
    SET NOCOUNT OFF

    RETURN @@RowCount
END
G
[解决办法]
--由于SELECT比DISTINCT先执行。所以你可以再套一层,先DISTINCT完后,再用ROW_NUMBER(),参考:http://blog.csdn.net/wwwwgou/article/details/6316796
--你的代码可以修改如下:

CREATE PROCEDURE [dbo].[GetRecordFromPage] 
    @SelectList            VARCHAR(2000),    --欲选择字段列表
    @TableSource        VARCHAR(100),    --表名或视图表 
    @SearchCondition    VARCHAR(2000),    --查询条件 


    @OrderExpression    VARCHAR(1000),    --排序表达式
    @PageIndex            INT = 1,        --页号,从0开始
    @PageSize            INT = 10        --页尺寸
AS 
BEGIN
    IF @SelectList IS NULL or LTRIM(RTRIM(@SelectList)) = ''
    BEGIN
        SET @SelectList = '*'
    END
    PRINT @SelectList

    SET @SearchCondition = ISNULL(@SearchCondition,'')
    SET @SearchCondition = LTRIM(RTRIM(@SearchCondition))
    IF @SearchCondition <> '' 
    BEGIN
        IF UPPER(SUBSTRING(@SearchCondition,1,5)) <> 'Where'
        BEGIN
            SET @SearchCondition = 'Where ' + @SearchCondition
        END
    END
    PRINT @SearchCondition

    SET @OrderExpression = ISNULL(@OrderExpression,'')
    SET @OrderExpression = LTRIM(RTRIM(@OrderExpression))
    IF @OrderExpression <> ''
    BEGIN
        IF UPPER(SUBSTRING(@OrderExpression,1,5)) <> 'Where'
        BEGIN
            SET @OrderExpression = 'ORDER BY ' + @OrderExpression 
        END
    END
    PRINT @OrderExpression

    IF @PageIndex IS NULL or @PageIndex < 1
    BEGIN
        SET @PageIndex = 1
    END
    PRINT @PageIndex
    IF @PageSize IS NULL or @PageSize < 1
    BEGIN
        SET @PageSize = 10
    END


    PRINT  @PageSize

    DECLARE @SqlQuery VARCHAR(4000)

    SET @SqlQuery='Select '+@SelectList+',RowNumber from (' +
'Select '+@SelectList+',ROW_NUMBER() OVER( '+ @OrderExpression +') AS RowNumber 
    FROM (Select DISTINCT ' + @SelectList + 
          ' FROM '+@TableSource+' '+ @SearchCondition +') AS RowNumberTableSource ) as T
    Where RowNumber BETWEEN ' + CAST(((@PageIndex - 1)* @PageSize+1) AS VARCHAR) 
    + ' AND ' + CAST((@PageIndex * @PageSize) AS VARCHAR) 
--    orDER BY ' + @OrderExpression
    PRINT @SqlQuery
    SET NOCOUNT ON
    EXECUTE(@SqlQuery)
    SET NOCOUNT OFF

    RETURN @@RowCount
END
GO

--测试:
EXEC [GetRecordFromPage] 'number', 'master..spt_values', 'number=1', 'number desc', 1, 10
go
/*
numberRowNumber
11
*/


[解决办法]
引用:
谢谢楼上,昨天我也套了一层,但是如果是多表查询的话,要注意排序字段的使用。

其实个人不建议用通用的分页存储过程。
#1.无法进行某些优化
#2.消耗CPU编译时间
#3.无法参数化,可能会引起SQL注入风险
#4.传字段名和表名时,指定别名时,要特别注意;如果无别名,就要保证关联表中无重复字段
建议生产环境,不要使用。

热点排行