存储过程要删除行,然后重新编号列

时间:2013-12-12 17:17:11

标签: stored-procedures sql-server-2008-r2

我需要一个程序来删除TBL_1TASK_ID@FirstID之间@LastIDPROJECT_ID = @PROJECT_ID

之间的行TASK_ID

然后将task_ID重新编号为顺序(这就是问题所在)

ID (int PK), TASK_ID (INT), project_id (INT), other columns 必须是连续的,以便我正在使用的网格能够正常运行。

表结构是

{{1}}

我完全不知道如何使用存储过程执行此操作。我在前端应用程序中有一个处理此问题的方法,但我知道SP会更好,我无法弄清楚如何解决这个问题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

鉴于此样本数据:

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时,我不知道你打算做什么......