如何在SQL Server(T-SQL)中重新组织页面顺序

时间:2011-03-10 08:47:43

标签: sql sql-server tsql

我正在尝试开发基于“文章”的系统,数据库中可以有一个文章条目,然后链接到该ArticleData的文章数据很多。

现在我正在尝试正确更新PageOrder。我希望数字始终保持一致,例如1到15。我不希望页码像这样。 1,1,3,6,8,9,10 ......它应该只是1,2,3,4,5,6,7。

我在为文章添加新记录时设法完成,因为我插入新记录然后成功重新计算排序。问题是当我想改变官方记录时。例如:

假设我有5页。
  - 第1页,
  - 第2页,
  - 第3页,
  - 第4页,
  - 第5页

让我们说我希望成为第三页   - 第1页,
  - 第2页,
  - 第4页,
  - 第5页,
  - 第3页

现在索引我希望能够重新编制索引,使其变得像它应该的那样。

现在的问题是......如何在T-SQL过程中执行此操作(SQL Server 2005)?

ALTER PROCEDURE [dbo].[Admin_InsertOrUpdateArticle]
    @Id int = null
    ,@ArticleId int = null
    ,@Header varchar(50)
    ,@ParentId int = null
    ,@ArticleType int
    ,@DisplayOrder int = 0
    ,@Content text
    ,@ModifiedById int
    ,@ModifiedBy varchar(50)
    ,@ModifiedDate datetime
    ,@Subject varchar(100)
    ,@NewPage int
AS
BEGIN

    SET NOCOUNT ON;

    UPDATE 
        [Article]
        SET
            [Header] = @Header
            ,[ParentId] = @ParentId
            ,[DisplayOrder] = @DisplayOrder
            ,[Type] = @ArticleType
        WHERE
            [Article].[Id] = @ArticleId

    -- If Article does not exists then we don't have any record of even Article Data!
    -- NEW RECORD!
    IF(@@ROWCOUNT = 0)
        BEGIN

            INSERT INTO [Article]
            (
                [Header]
                ,[ParentId]
                ,[DisplayOrder]
                ,[Type]
            )
            VALUES
            (
                @Header
                ,@ParentId
                ,@DisplayOrder
                ,@ArticleType
            );

            INSERT INTO [ArticleData]
            (
                [ArticleId]
                ,[Content]
                ,[CreatedBy]
                ,[CreatedById]
                ,[ModifiedBy]
                ,[ModifiedById]
                ,[PostDate]
                ,[ModifiedDate]
                ,[Subject]
                ,[PageOrder]
            )
            VALUES
            (
                @@IDENTITY
                ,@Content
                ,@ModifiedBy
                ,@ModifiedById
                ,@ModifiedBy
                ,@ModifiedById
                ,@ModifiedDate
                ,@ModifiedDate
                ,@Subject
                ,1 -- First Page!!!
            )

        END
    ELSE
        BEGIN

            -- We do have a Article Record, therefore we update the current page and check to see if it is a new page!
            UPDATE 
                [ArticleData]
                SET
                    [Content] = @Content
                    ,[Subject] = @Subject
                    ,[ModifiedBy] = @ModifiedBy
                    ,[ModifiedById] = @ModifiedById
                    ,[ModifiedDate] = @ModifiedDate
                WHERE
                    [ArticleData].[Id] = @Id AND
                    [ArticleData].[ArticleId] = @ArticleId

            -- Are we a new Article Data?
            IF( @@ROWCOUNT = 0 )
            BEGIN   

                -- We are lets check to see if the page we want this article for exists
                IF EXISTS ( SELECT [PageOrder] FROM [ArticleData] WHERE [ArticleId] = @ArticleId AND [PageOrder] = @NewPage )
                BEGIN

                    -- It does exists therefore we need to reorder the pages
                    UPDATE 
                        [ArticleData] 
                        SET 
                            [PageOrder] = A.PageOrder + 1
                            FROM [ArticleData] A 
                        WHERE 
                            A.PageOrder >= @NewPage AND 
                            [ArticleId] = @ArticleId

                    -- We now Insert The New data that we want at that page
                    INSERT INTO [ArticleData]
                    (
                        [ArticleId]
                        ,[Content]
                        ,[CreatedBy]
                        ,[CreatedById]
                        ,[ModifiedBy]
                        ,[ModifiedById]
                        ,[PostDate]
                        ,[ModifiedDate]
                        ,[Subject]
                        ,[PageOrder]
                    )
                    VALUES
                    (
                        @ArticleId
                        ,@Content
                        ,@ModifiedBy
                        ,@ModifiedById
                        ,@ModifiedBy
                        ,@ModifiedById
                        ,@ModifiedDate
                        ,@ModifiedDate
                        ,@Subject
                        ,@NewPage
                    )   

                END     
                ELSE
                BEGIN

                    -- Since that page we want to add is not in reach we will simply add it to the very last page                   
                    INSERT INTO [ArticleData]
                    (
                        [ArticleId]
                        ,[Content]
                        ,[CreatedBy]
                        ,[CreatedById]
                        ,[ModifiedBy]
                        ,[ModifiedById]
                        ,[PostDate]
                        ,[ModifiedDate]
                        ,[Subject]
                        ,[PageOrder]
                    )
                    VALUES
                    (
                        @ArticleId
                        ,@Content
                        ,@ModifiedBy
                        ,@ModifiedById
                        ,@ModifiedBy
                        ,@ModifiedById
                        ,@ModifiedDate
                        ,@ModifiedDate
                        ,@Subject
                        ,(SELECT COUNT(Id)+1 FROM [ArticleData] WHERE [ArticleId] = @ArticleId) -- Add new Page as Last Record
                    )   

                END     

            END
            ELSE
            BEGIN

                -- The article did update therefore lets reorder our pages based on the new page defined
                -- Does this page in the article exists?  IF it does lets update the pages
                IF EXISTS ( SELECT [PageOrder] FROM [ArticleData] WHERE [ArticleId] = @ArticleId AND [PageOrder] = @NewPage )
                BEGIN

                    -- Update all pages with new numbers 
                    UPDATE 
                        [ArticleData] 
                        SET 
                            [PageOrder] = A.PageOrder + 1
                            FROM [ArticleData] A 
                        WHERE 
                            A.PageOrder >= @NewPage AND 
                            [ArticleId] = @ArticleId

                    -- Update THIS article data with the new page number
                    UPDATE 
                    [ArticleData]
                    SET
                        [PageOrder] = @NewPage
                    WHERE
                        [ArticleData].[Id] = @Id AND
                        [ArticleData].[ArticleId] = @ArticleId

                END
                ELSE
                BEGIN

                    -- Page doesn't exists because what we want to change it to is to far out of range for example if there are only 5 pages, then the ordering will simply set this page to the last index
                    UPDATE 
                    [ArticleData]
                    SET
                        [PageOrder] = (SELECT COUNT(Id) FROM [ArticleData] WHERE [Id] = @Id AND [ArticleId] = @ArticleId)
                    WHERE
                        [ArticleData].[Id] = @Id AND
                        [ArticleData].[ArticleId] = @ArticleId

                END

            END

        END

END

2 个答案:

答案 0 :(得分:3)

重新编号页面相对简单,但我无法判断您是否要将其插入现有代码中,在这种情况下,不确定这会发生什么:

DECLARE @OldPageID int
DECLARE @NewPageID int

set @OldPageID = 3
set @NewPageID = 5

UPDATE
    Page
SET
    PageID = CASE
        WHEN PageID = @OldPageID THEN @NewPageID ELSE
        WHEN @OldPageID < @NewPageID THEN PageID -1 ELSE PageID + 1 END
where
    PageID between
        CASE WHEN @OldPageID < @NewPageID THEN @OldPageID ELSE @NewPageID END
        and
        CASE WHEN @OldPageID < @NewPageID THEN @NewPageID ELSE @OldPageID END

答案 1 :(得分:0)

这是我的最终结果

ALTER PROCEDURE [dbo].[Admin_InsertOrUpdateArticle]
    @Id int = null
    ,@ArticleId int = null
    ,@Header varchar(50)
    ,@ParentId int = null
    ,@ArticleType int
    ,@DisplayOrder int = 0
    ,@Content text
    ,@ModifiedById int
    ,@ModifiedBy varchar(50)
    ,@ModifiedDate datetime
    ,@Subject varchar(100)
    ,@NewPage int
AS
BEGIN

    SET NOCOUNT ON;

    UPDATE 
        [Article]
        SET
            [Header] = @Header
            ,[ParentId] = @ParentId
            ,[DisplayOrder] = @DisplayOrder
            ,[Type] = @ArticleType
        WHERE
            [Article].[Id] = @ArticleId

    -- If Article does not exists then we don't have any record of even Article Data!
    -- NEW RECORD!
    IF(@@ROWCOUNT = 0)
        BEGIN

            INSERT INTO [Article]
            (
                [Header]
                ,[ParentId]
                ,[DisplayOrder]
                ,[Type]
            )
            VALUES
            (
                @Header
                ,@ParentId
                ,@DisplayOrder
                ,@ArticleType
            );

            INSERT INTO [ArticleData]
            (
                [ArticleId]
                ,[Content]
                ,[CreatedBy]
                ,[CreatedById]
                ,[ModifiedBy]
                ,[ModifiedById]
                ,[PostDate]
                ,[ModifiedDate]
                ,[Subject]
                ,[PageOrder]
            )
            VALUES
            (
                @@IDENTITY
                ,@Content
                ,@ModifiedBy
                ,@ModifiedById
                ,@ModifiedBy
                ,@ModifiedById
                ,@ModifiedDate
                ,@ModifiedDate
                ,@Subject
                ,1 -- First Page!!!
            )

        END
    ELSE
        BEGIN

            -- We do have a Article Record, therefore we update the current page and check to see if it is a new page!
            UPDATE 
                [ArticleData]
                SET
                    [Content] = @Content
                    ,[Subject] = @Subject
                    ,[ModifiedBy] = @ModifiedBy
                    ,[ModifiedById] = @ModifiedById
                    ,[ModifiedDate] = @ModifiedDate
                WHERE
                    [ArticleData].[Id] = @Id AND
                    [ArticleData].[ArticleId] = @ArticleId

            -- Are we a new Article Data?
            IF( @@ROWCOUNT = 0 )
            BEGIN   

                -- We are lets check to see if the page we want this article for exists
                IF EXISTS ( SELECT [PageOrder] FROM [ArticleData] WHERE [ArticleId] = @ArticleId AND [PageOrder] = @NewPage )
                BEGIN

                    -- It does exists therefore we need to reorder the pages
                    UPDATE 
                        [ArticleData] 
                        SET 
                            [PageOrder] = A.PageOrder + 1
                            FROM [ArticleData] A 
                        WHERE 
                            A.PageOrder >= @NewPage AND 
                            [ArticleId] = @ArticleId

                    -- We now Insert The New data that we want at that page
                    INSERT INTO [ArticleData]
                    (
                        [ArticleId]
                        ,[Content]
                        ,[CreatedBy]
                        ,[CreatedById]
                        ,[ModifiedBy]
                        ,[ModifiedById]
                        ,[PostDate]
                        ,[ModifiedDate]
                        ,[Subject]
                        ,[PageOrder]
                    )
                    VALUES
                    (
                        @ArticleId
                        ,@Content
                        ,@ModifiedBy
                        ,@ModifiedById
                        ,@ModifiedBy
                        ,@ModifiedById
                        ,@ModifiedDate
                        ,@ModifiedDate
                        ,@Subject
                        ,@NewPage
                    )   

                END     
                ELSE
                BEGIN

                    -- Since that page we want to add is not in reach we will simply add it to the very last page                   
                    INSERT INTO [ArticleData]
                    (
                        [ArticleId]
                        ,[Content]
                        ,[CreatedBy]
                        ,[CreatedById]
                        ,[ModifiedBy]
                        ,[ModifiedById]
                        ,[PostDate]
                        ,[ModifiedDate]
                        ,[Subject]
                        ,[PageOrder]
                    )
                    VALUES
                    (
                        @ArticleId
                        ,@Content
                        ,@ModifiedBy
                        ,@ModifiedById
                        ,@ModifiedBy
                        ,@ModifiedById
                        ,@ModifiedDate
                        ,@ModifiedDate
                        ,@Subject
                        ,(SELECT COUNT(Id)+1 FROM [ArticleData] WHERE [ArticleId] = @ArticleId) -- Add new Page as Last Record
                    )   

                END     

            END
            ELSE
            BEGIN

                -- The article did update therefore lets reorder our pages based on the new page defined        
                DECLARE @OldPage int
                SET @OldPage = (SELECT [PageOrder] FROM [ArticleData] WHERE [ArticleId] = @ArticleId AND [Id] = @Id) -- Get the old Page from the Id we have

                IF ( @OldPage != @NewPage )
                BEGIN
                    UPDATE
                        [ArticleData]
                    SET
                        PageOrder = CASE
                                WHEN PageOrder = @OldPage THEN @NewPage
                                WHEN @OldPage < @NewPage THEN PageOrder -1 ELSE PageOrder + 1 END
                    WHERE
                        PageOrder BETWEEN
                            CASE WHEN @OldPage < @NewPage THEN @OldPage ELSE @NewPage END
                            AND
                            CASE WHEN @OldPage < @NewPage THEN @NewPage ELSE @OldPage END
                END

            END

        END

END