如果您在移动位置时使用更新表中所有相关位置的 SP,这应该可以完成工作:
USE Sandbox;
GO
--Small sample set
CREATE TABLE dbo.Playlist (SongID int,
PlaylistID int,
Position int);
INSERT INTO dbo.Playlist (SongID,
PlaylistID,
Position)
VALUES(1,1,1),
(3,1,2),
(5,1,3),
(2,1,4),
(2,2,1),
(10,2,2);
GO
--Check data
SELECT *
FROM dbo.Playlist;
GO
--CREATE the SP
CREATE PROC dbo.MoveSongPosition @PlaylistID int,
@SongID int,
@NewPosition int
AS BEGIN
UPDATE P
SET Position = CASE WHEN SongID = @SongID THEN @NewPosition ELSE Position +1 END
FROM dbo.Playlist P
WHERE P.PlaylistID = @PlaylistID
AND (P.SongID = @SongID
OR P.Position BETWEEN @NewPosition AND (SELECT sq.Position
FROM dbo.Playlist sq
WHERE sq.SongID = @SongID
AND sq.PlaylistID = @PlaylistID));
END
GO
--Run and test the SP
EXEC dbo.MoveSongPosition @PlaylistID = 1,
@SongID = 2,
@NewPosition = 2;
GO
--Check the new data
SELECT *
FROM dbo.Playlist;
GO
--Clean up
DROP PROC dbo.MoveSongPosition;
DROP TABLE dbo.Playlist;
此解决方案假定您使用的是 SQL Server;自从我发表评论以来,您还没有更新您的标签,所以我们不知道您真正使用的是什么 RDBM。
编辑:逻辑变化,相信我已经更正了。
CREATE PROC dbo.MoveSongPosition @PlaylistID int,
@SongID int,
@NewPosition int
AS BEGIN
UPDATE P
SET Position = CASE WHEN P.SongID = @SongID THEN @NewPosition
WHEN P.Position = @NewPosition THEN P.Position + V.Direction
WHEN P.Position < @NewPosition THEN P.Position - V.Direction
WHEN P.Position > @NewPosition THEN P.Position + V.Direction
END
FROM dbo.Playlist P
CROSS APPLY (SELECT ca.Position
FROM dbo.Playlist ca
WHERE ca.PlaylistID = P.PlaylistID
AND ca.SongID = @SongID) CS
CROSS APPLY (VALUES(CASE WHEN CS.Position < @NewPosition THEN -1
WHEN @NewPosition < CS.Position THEN 1
ELSE 0 END)) V(Direction)
WHERE P.PlaylistID = @PlaylistID
AND ((P.Position >= @NewPosition AND P.Position <= CS.Position
OR (P.Position >= CS.Position AND P.Position <= @NewPosition)));
END