Stored procedures 删除行然后对列重新编号的存储过程

Stored procedures 删除行然后对列重新编号的存储过程,stored-procedures,sql-server-2008-r2,Stored Procedures,Sql Server 2008 R2,我需要一个过程来删除TBL_1中的行,其中TASK_ID介于@FirstID和@LastID和PROJECT_ID=@PROJECT_ID 然后将TASK\u ID重新编号为顺序(这就是问题所在) task\u ID必须是顺序的,才能使我正在使用的网格正常工作 表结构是 ID (int PK), TASK_ID (INT), project_id (INT), other columns 我完全不知道如何使用存储过程来实现这一点。我在前端应用程序中有一个方法可以处理这个问题,但我知道SP会更

我需要一个过程来删除
TBL_1
中的行,其中
TASK_ID
介于
@FirstID
@LastID
PROJECT_ID=@PROJECT_ID

然后将
TASK\u ID
重新编号为顺序(这就是问题所在)

task\u ID
必须是顺序的,才能使我正在使用的网格正常工作

表结构是

ID (int PK), TASK_ID (INT), project_id (INT), other columns 

我完全不知道如何使用存储过程来实现这一点。我在前端应用程序中有一个方法可以处理这个问题,但我知道SP会更好,我不知道如何解决这个问题。非常感谢您的帮助。

鉴于此示例数据:

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\u ID Task\u ID说明
----------  -------  -----------
1任务1
1 2任务5
1 3任务6
清理:

DROP TABLE dbo.TBL_1;

现在,我的观点是。。。 …一旦建立了此任务ID列,就没有理由更新它。您试图将数据库中的标识符和前端代码中的显示项视为相同的东西。为什么不能将此查询提供给前端代码:

SELECT Task_ID, SequentialID = ROW_NUMBER() OVER (ORDER BY Task_ID),
  Description FROM dbo.TBL_1 WHERE Project_ID = 1;
现在,UI可以显示SequentialID列,但当它传回要更新/删除/您拥有的内容的ID时,它会传递存储在数据库中的实际任务ID(您的网格不必关心,用户应该不知道)。这是一个额外的抽象层,但它可以防止表中出现大量不必要的搅动


我不知道的是,当人们想要删除任务1、3和12,或者交换任务5和6时,您打算怎么做…

给定以下示例数据:

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\u ID Task\u ID说明
----------  -------  -----------
1任务1
1 2任务5
1 3任务6
清理:

DROP TABLE dbo.TBL_1;

现在,我的观点是。。。 …一旦建立了此任务ID列,就没有理由更新它。您试图将数据库中的标识符和前端代码中的显示项视为相同的东西。为什么不能将此查询提供给前端代码:

SELECT Task_ID, SequentialID = ROW_NUMBER() OVER (ORDER BY Task_ID),
  Description FROM dbo.TBL_1 WHERE Project_ID = 1;
现在,UI可以显示SequentialID列,但当它传回要更新/删除/您拥有的内容的ID时,它会传递存储在数据库中的实际任务ID(您的网格不必关心,用户应该不知道)。这是一个额外的抽象层,但它可以防止表中出现大量不必要的搅动


我不知道的是,当人们想要删除任务1、3和12,或者交换任务5和6时,您打算怎么做…

给定以下示例数据:

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\u ID Task\u ID说明
----------  -------  -----------
1任务1
1 2任务5
1 3任务6
清理:

DROP TABLE dbo.TBL_1;

现在,我的观点是。。。 …一旦建立了此任务ID列,就没有理由更新它。您试图将数据库中的标识符和前端代码中的显示项视为相同的东西。为什么不能将此查询提供给前端代码:

SELECT Task_ID, SequentialID = ROW_NUMBER() OVER (ORDER BY Task_ID),
  Description FROM dbo.TBL_1 WHERE Project_ID = 1;
现在,UI可以显示SequentialID列,但当它传回要更新/删除/您拥有的内容的ID时,它会传递存储在数据库中的实际任务ID(您的网格不必关心,用户应该不知道)。这是一个额外的抽象层,但它可以防止表中出现大量不必要的搅动


我不知道的是,当人们想要删除任务1、3和12,或者交换任务5和6时,您打算怎么做…

给定以下示例数据:

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\u ID Task\u ID说明
----------  -------  -----------
1任务1
1 2任务5
1 3任务6
清理:

DROP TABLE dbo.TBL_1;

现在,我的观点是。。。 …一旦建立了此任务ID列,就没有理由更新它。您试图将数据库中的标识符和前端代码中的显示项视为相同的东西。为什么不能将此查询提供给前端代码:

SELECT Task_ID, SequentialID = ROW_NUMBER() OVER (ORDER BY Task_ID),
  Description FROM dbo.TBL_1 WHERE Project_ID = 1;
现在,UI可以显示SequentialID列,但当它传回要更新/删除/您拥有的内容的ID时,它会传递存储在数据库中的实际任务ID(您的网格不必关心,用户应该不知道)。这是一个额外的抽象层,但它可以防止表中出现大量不必要的搅动



我不知道的是,当人们想要删除任务1、3和12,或者交换任务5和6时,你打算怎么做…

按任务排序如何?基于什么顺序?如果您可以在运行更新的查询中确定这一点,为什么还要麻烦存储它呢?只需在查询时生成序列号,它就不必经常运行以更新。换句话说,您可能还不熟悉。没错,我不熟悉行号。任务id列是顺序1,2,3,4,5。。。。如果我删除2-4,那么剩下的第5行现在必须是2,第6行现在应该是3,那么按任务排序的顺序基于什么?如果您可以在运行更新的查询中确定这一点,为什么还要麻烦存储它呢?只需在查询时生成序列号,它就不必一直运行以保持最新。换句话说,您可能还不熟悉。是的,我不熟悉行号。任务id列是顺序1,