Универсальный рабочий процесс и DFDs могут быть очень полезны для сложных процессов. Все другое схематическое изображение (ОСОБЕННО UML) имеет, по моему опыту, без исключения, болезненная пустая трата времени и усилие.
Заказ не должен быть вашим первичным ключом; выполняйте обновления, используя первичный ключ в предложении 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
Вы действительно хотите вернуться и посмотреть на результаты функции ajax. Посмотрите, сможете ли вы получить список переупорядоченных элементов вместо только нового порядка в списке.
Вы можете написать функцию (на C # / VB), чтобы определить это для вас в коде с учетом списков до и после. Как только у вас есть изменения дельты, вы можете выполнить транзакцию обновления с одной командой обновления для каждого переупорядочения.
Если вы хотите работать только с новым порядком. Попробуйте добавить новый столбец под названием neworder и обновите его. Затем массовое обновление currentcolumn = newcolumn после завершения цикла.
Вы можете сделать что-то вроде
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;
(НЕПРОВЕРЕНО, ЭТО ПРОСТО УКАЗАТЕЛЬ)