Use following code to move and rebuild indexes, it adds element after desired elements and shifts others (answer based on the comment clarifications ) :
This is slimmer version:
DECLARE @SortIndex int,@MoveTo int, @CurrentSortIndex int
SET @CurrentSortIndex = (SELECT SortIndex FROM @T WHERE ID = 45) --D
SET @MoveTo = 2
UPDATE--D
@T
SET
SortIndex = @MoveTo
WHERE
ID = 45
UPDATE
@T
SET
SortIndex = SortIndex - ((@MoveTo-@CurrentSortIndex)/(ABS(@MoveTo-@CurrentSortIndex)))
WHERE
(
SortIndex BETWEEN @CurrentSortIndex AND @MoveTo
OR
SortIndex BETWEEN @MoveTo AND @CurrentSortIndex
)
AND
ID != 45
Full example of moving A to position 2, also sqlfidle link http://sqlfiddle.com/#!3/d41d8/5918:
DECLARE @T TABLE
(
ID int,
Name char(1),
SortIndex int
)
INSERT @T
SELECT 21, 'A', 1 UNION ALL
SELECT 23, 'B', 2 UNION ALL
SELECT 35, 'C', 3 UNION ALL
SELECT 45, 'D', 4 UNION ALL
SELECT 55, 'E', 5
DECLARE @SortIndex int,@MoveTo int, @CurrentSortIndex int
DECLARE @IDToMove INT
SET @IDToMove = 21--A
SET @CurrentSortIndex = (SELECT SortIndex FROM @T WHERE ID = @IDToMove)
SET @MoveTo = 2
UPDATE
@T
SET
SortIndex = @MoveTo
WHERE
ID = @IDToMove
UPDATE
@T
SET
SortIndex = SortIndex - ((@MoveTo-@CurrentSortIndex)/(ABS(@MoveTo-@CurrentSortIndex)))
WHERE
(
SortIndex BETWEEN @CurrentSortIndex AND @MoveTo
OR
SortIndex BETWEEN @MoveTo AND @CurrentSortIndex
)
AND
ID != @IDToMove
SELECT * FROM @T ORDER BY SortIndex
Initial version:
DECLARE @SortIndex int,@MoveTo int, @CurrentSortIndex int
SET @CurrentSortIndex = (SELECT SortIndex FROM @T WHERE ID = 21) --A
SET @MoveTo = 2
UPDATE--A
@T
SET
SortIndex = @MoveTo
WHERE
ID = 21
IF @MoveTo > @CurrentSortIndex
UPDATE
@T
SET
SortIndex = SortIndex - 1
WHERE
SortIndex BETWEEN @CurrentSortIndex AND @MoveTo
AND
ID != 21
IF @MoveTo < @CurrentSortIndex
UPDATE
@T
SET
SortIndex = SortIndex + 1
WHERE
SortIndex BETWEEN @MoveTo AND @CurrentSortIndex
AND
ID != 21