SQL大规模行重新排序

SQL大规模行重新排序,sql,ajax,sql-update,Sql,Ajax,Sql Update,我有一个包含记录列表的表和一个名为order的列。我有一个AJAX脚本来上下拖拽表中的行,我想用它来执行查询,并在拖拽行时对它们重新排序 在PHP中,我执行查询以获取记录的当前顺序。例1、2、3、4 AJAX函数在拖放完成后传递新命令,例如3、1、2、4 是否有一种简单的方法可以根据新值一次性重新排列记录?我能看到的另一种选择是循环使用更新语句,例如SET order=1,其中order=3 但这肯定会导致两条记录具有相同的值吗 抱歉,我知道这个描述可能有点让人困惑。您真的想回去看看ajax函数

我有一个包含记录列表的表和一个名为order的列。我有一个AJAX脚本来上下拖拽表中的行,我想用它来执行查询,并在拖拽行时对它们重新排序

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

是否有一种简单的方法可以根据新值一次性重新排列记录?我能看到的另一种选择是循环使用更新语句,例如SET order=1,其中order=3

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


抱歉,我知道这个描述可能有点让人困惑。

您真的想回去看看ajax函数的结果。查看是否可以获得重新排序的元素列表,而不仅仅是新的列表顺序

您可以在C/VB中编写一个函数,在给定前后列表的代码中为您确定这一点。一旦有了增量更改,就可以发出一个更新事务,每个重新排序一个更新命令


如果你只想处理新订单。尝试添加一个名为neworder的新列,并更新此列。然后批量更新currentcolumn=newcolumn一旦完成循环。

顺序不应该是您的主键;使用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等操作。

如果您知道新行位置,则可以执行以下操作:

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

你可以这样做

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;

未经测试,这只是一个指针

这会起作用,但如果多个客户端同时更新订单,您希望在一个事务中执行所有更新。这是一个常见的解决方案。如果在重新排序的行之后有很多行,这可能会变得很难处理。在这种情况下,我更喜欢使用“下一个”列,并将其视为链接列表。这将任何可能的重新排序操作减少到最多三行更新。@Brent Rockwood。另一种通常更容易迁移的方法是使用订单100、200、300,然后您可以轻松地插入订单150。这大大减少了重新编号的需要。