鉴于此示例数据:
USE tempdb;
GO
CREATE TABLE dbo.TBL_1
(
Project_ID INT,
Task_ID INT,
Description VARCHAR(32),
PRIMARY KEY (Project_ID, Task_ID)
);
INSERT dbo.TBL_1(Project_ID, Task_ID, Description)
VALUES(1,1,'Task 1'),(1,2,'Task 2'),(1,3,'Task 3'),
(1,4,'Task 4'),(1,5,'Task 5'),(1,6,'Task 6');
GO
创建存储过程:
CREATE PROCEDURE dbo.RenumberTasksWithRedundantInformation
@Project_ID INT,
@FirstTaskID INT,
@LastTaskID INT
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION;
DELETE dbo.TBL_1
WHERE Project_ID = @Project_ID
AND Task_ID BETWEEN @FirstID AND @LastID;
;WITH x AS
(
SELECT Project_ID, Task_ID, NewTaskID = ROW_NUMBER() OVER (ORDER BY Task_ID)
FROM dbo.TBL_1 WHERE Project_ID = @Project_ID
)
UPDATE x SET Task_ID = NewTaskID;
COMMIT TRANSACTION;
END
GO
现在,这样称呼它:
EXEC dbo.RenumberTasksWithRedundantInformation
@Project_ID = 1,
@FirstTaskID = 2,
@LastTaskID = 4;
然后运行查询:
SELECT Project_ID, Task_ID, Description FROM dbo.TBL_1 WHERE Project_ID = 1;
结果:
Project_ID Task_ID Description
---------- ------- -----------
1 1 Task 1
1 2 Task 5
1 3 Task 6
清理:
DROP TABLE dbo.TBL_1;
现在,我的意思是……
...一旦创建此Task_ID 列,就没有真正的理由更新它。您试图将数据库中的标识符和前端代码中的显示项视为同一事物。为什么你不能把这个查询交给你的前端代码:
SELECT Task_ID, SequentialID = ROW_NUMBER() OVER (ORDER BY Task_ID),
Description FROM dbo.TBL_1 WHERE Project_ID = 1;
现在,UI 可以显示 SequentialID 列,但是当它传回 ID 以更新/删除/你有什么时,它会传递存储在数据库中的实际 Task_ID(你的网格没有'不必关心,哪些用户不应该知道)。这是一个额外的抽象层,但它可以防止您的表格中出现大量不必要的混乱。
我不知道的是,当人们想要删除任务 1、3 和 12,或者交换任务 5 和 6 时,你打算做什么......