SQL批量重新排序行

时间:2009-09-08 12:45:58

标签: sql ajax sql-update

我有一个包含记录列表的表,以及一个名为order的列。我有一个AJAX脚本来向上或向下拖放表格行,我想用它来执行查询,在拖动行时对行进行重新排序。

在PHP中,我执行查询以获取记录的当前顺序。例如1,2,3,4 在拖放完成后,AJAX函数传递新顺序,例如3,1,2,4

是否有一种简单的方法可以根据新值一次性重新排序记录?我能看到的唯一其他选择是循环遍历UPDATE语句,例如SET order = 1,其中order = 3

但这肯定会导致2条记录具有相同的值?

抱歉,我知道这种描述可能会有些混乱。

5 个答案:

答案 0 :(得分:6)

订单不应该是您的主键;使用where子句中的主键进行更新。

如果你真的想,你可以使用相当长的CASE语句在一个查询中完成所有操作。例如:

UPDATE foo
  SET order = CASE order
    WHEN 1 THEN 2
    WHEN 2 THEN 3
    WHEN 3 THEN 4
    WHEN 4 THEN 5
  END
WHERE order IN (1,2,3,4)

(请记住,SQL语句的行为就像它们同时更改所有值一样,因此不会执行更改1到2,然后更改为3等操作。)

答案 1 :(得分:2)

我在另一个帖子中描述了一个可能的解决方案: How can I reorder rows in sql database

答案 2 :(得分:1)

你真的想回头看看ajax功能结果。看看你是否可以获得重新排序的元素列表,而不仅仅是新的列表顺序。

您可以编写一个函数(在C#/ VB中),在给定前后列表的代码中为您确定。完成增量更改后,您可以发出更新事务,每次重新订购时都会有一个更新命令。

如果您只想使用新订单。尝试添加名为neworder的新列并更新它。然后批量更新currentcolumn = newcolumn一旦完成循环。

答案 3 :(得分:1)

如果你知道新的行位置,你可以这样做:

CREATE PROCEDURE [proc_UpdateCountryRowOrder]
    @ID UNIQUEIDENTIFIER,
    @NewPosition INT
AS

SET NOCOUNT ON

DECLARE @CurrentPosition INT
DECLARE @MaximumPosition INT

IF (@NewPosition < 1) SET @NewPosition = 1

SELECT @CurrentPosition = [Countries].[Order]
FROM [Countries]
WHERE [Countries].[ID] = @ID

SELECT @MaximumPosition = MAX([Countries].[Order])
FROM [Countries]

IF (@NewPosition > @MaximumPosition) SET @NewPosition = @MaximumPosition

IF (@NewPosition <> @CurrentPosition)
BEGIN
    IF (@NewPosition < @CurrentPosition)
    BEGIN
        BEGIN TRAN

        UPDATE [Countries]
        SET [Countries].[Order] = [Countries].[Order] + 1
        WHERE [Countries].[Order] >= @NewPosition
        AND [Countries].[Order] < @CurrentPosition

        UPDATE [Countries]
        SET [Countries].[Order] = @NewPosition
        WHERE ID = @ID

        COMMIT TRAN
    END
    ELSE
    BEGIN
        BEGIN TRAN

        UPDATE [Countries]
        SET [Countries].[Order] = [Countries].[Order] - 1
        WHERE [Countries].[Order] <= @NewPosition
        AND [Countries].[Order] > @CurrentPosition

        UPDATE [Countries]
        SET [Countries].[Order] = @NewPosition
        WHERE ID = @ID

        COMMIT TRAN
    END
END
GO

答案 4 :(得分:0)

您可以执行类似

的操作
BEGIN
UPDATE Table SET order = order + 1 WHERE order >= new_pos
UPDATE Table SET order = new_pos WHERE order = old_pos
UPDATE Table SET order = order - 1 WHERE order < old_pos AND order > new_pos
COMMIT;

(UNTESTED,这只是一个指针)