Следующий код демонстрирует один способ изменения положения строки в заданном порядке отображения и перетасовывания любых других строк, чтобы учесть изменение. Используя выражение case
, один оператор update
может выбирать и обновлять различные строки.
Примечание: он должен быть заключен в подходящую транзакцию для использования в The Real Word.
-- Sample data.
declare @Samples as Table ( Id Int Identity, DisplayOrder Int );
insert into @Samples ( DisplayOrder ) values ( 1 ), ( 2 ), ( 3 ), ( 4 );
select * from @Samples order by DisplayOrder;
-- We need a few variables.
declare @PreviousDisplayOrder as Int;
declare @Id as Int, -- Row to be moved.
@DisplayOrder as Int; -- New order for the row.
-- Pick a row to move and a new display order for it.
select @Id = 2, @DisplayOrder = 3;
-- Determine the previous display order for the row being moved.
select @PreviousDisplayOrder = DisplayOrder from @Samples where Id = @Id;
-- Display some useful tidbits.
select @PreviousDisplayOrder as PreviousDisplayOrder,
( select Min( DisplayOrder ) from ( values ( @DisplayOrder ), (@PreviousDisplayOrder ) ) M1( DisplayOrder ) ) as MinDisplayOrder,
( select Max( DisplayOrder ) from ( values ( @DisplayOrder ), (@PreviousDisplayOrder ) ) M2( DisplayOrder ) ) as MaxDisplayOrder;
-- Update the rows.
update @Samples
set DisplayOrder = case
-- Set the order of the repositioned row.
when Id = @Id then @DisplayOrder
-- Moving the repositioned row up (numerically).
when @DisplayOrder > @PreviousDisplayOrder and DisplayOrder <= @DisplayOrder then DisplayOrder - 1
-- Moving the repositioned row down (numerically).
when @DisplayOrder < @PreviousDisplayOrder and DisplayOrder >= @DisplayOrder then DisplayOrder + 1
else DisplayOrder
end
where
-- Only update the rows between the original and the new display orders.
DisplayOrder >= ( select Min( DisplayOrder ) from ( values ( @DisplayOrder ), (@PreviousDisplayOrder ) ) M1( DisplayOrder ) ) and
DisplayOrder <= ( select Max( DisplayOrder ) from ( values ( @DisplayOrder ), (@PreviousDisplayOrder ) ) M2( DisplayOrder ) );
-- Display the results.
select * from @Samples order by DisplayOrder;