循环遍历行并从同一个表中INSERT INTO SELECT

时间:2018-01-12 12:53:49

标签: sql-server

我试图在SQL-Server2012中创建一个存储过程,它将更新某些行,然后将它们重新插入到同一个表中,但是使用NULL或不同的计算值。

我的表'日程安排':

switch

我的表'任务':

CREATE TABLE [cil].[schedule](
[id] [int] IDENTITY(1,1) NOT NULL,
[taskFK] [int] NULL,
[scheduledDate] [smalldatetime] NULL,
[completionDate] [smalldatetime] NULL,
[rotaCycle] [smallint] NULL,
[result] [smallint] NULL,
 CONSTRAINT [PK_schedule] PRIMARY KEY CLUSTERED 

CONSTRAINT [PK_task] PRIMARY KEY CLUSTERED

现有存储过程:

CREATE TABLE [cil].[task](
[id] [int] IDENTITY(1,1) NOT NULL,
[standard] [varchar](250) NULL,
[equipFK] [int] NULL,
[areaFK] [smallint] NULL,

现在我想将RE-INSERT添加到上面的SP:

CREATE PROCEDURE [cil].[updateCompletionDate]
@equipID int,
@myCompletionDate datetime

AS   
UPDATE cil.schedule SET completionDate=@myCompletionDate
WHERE schedule.id IN (
SELECT schedule.id 
FROM cil.schedule
LEFT JOIN cil.task
ON cil.schedule.taskFK=cil.task.id
WHERE CAST(scheduledDate AS DATE)<=CAST(GetDate() AS DATE)
AND completionDate IS NULL
AND result IS NOT NULL
AND equipFK=@equipID);
GO

不知道如何遍历SP的第一部分的所有ID?

3 个答案:

答案 0 :(得分:0)

您可以使用output子句和delete表来完成此操作。我创建了下面的伪代码,让你知道这将如何工作 -

CREATE PROCEDURE [cil].[updateCompletionDate]
@equipID int,
@myCompletionDate datetime

AS   

DECLARE @MyTable table(  
    id int ,   
    taskFK int 
    ....  ); -- declare all required columns   

UPDATE cil.schedule SET completionDate=@myCompletionDate 
OUTPUT deleted.id,  
       deleted.taskFK -- list of required columns you want 
INTO @MyTable
WHERE schedule.id IN (
SELECT schedule.id 
FROM cil.schedule
LEFT JOIN cil.task
ON cil.schedule.taskFK=cil.task.id
WHERE CAST(scheduledDate AS DATE)<=CAST(GetDate() AS DATE)
AND completionDate IS NULL
AND result IS NOT NULL
AND equipFK=@equipID)


INSERT INTO cil.schedule (taskFK, scheduledDate, rotaCycle) 
select [required coluns] 
from @MyTableVa join cil.schedule -- all requied join conditions 

答案 1 :(得分:0)

您可以使用SQL Output clause更新您的表格并将受影响的行插入同一个表格

请查看以下简单示例脚本

/*
create table OutputClauseSample (
Id int identity(1,1),
Code varchar(10),
Val int
)
insert into OutputClauseSample select 'A',10
insert into OutputClauseSample select 'B',20
insert into OutputClauseSample select 'C',30
*/
update OutputClauseSample
set Val = 2 * Val
output (deleted.Code)
into OutputClauseSample (Code)
where id = 3

select * from OutputClauseSample

答案 2 :(得分:0)

这是我的程序,游标循环并重新插入修改后的正确数据:

CREATE PROCEDURE [cil].[addComplDateAnd_ReSchedule]

@equipID int,
@myCompletionDate datetime2(6)

AS   
/* add completion date */

UPDATE cil.schedule SET completionDate=@myCompletionDate
WHERE schedule.id IN (
                    SELECT schedule.id 
                    FROM cil.schedule
                    LEFT JOIN cil.task ON cil.schedule.taskFK=cil.task.id
                    WHERE CAST(scheduledDate AS DATE)<=CAST(GetDate() AS DATE)
                    AND completionDate IS NULL
                    AND result IS NOT NULL
                    AND equipFK=@equipID);

/* reschedule tasks */

DECLARE @nextTaskID AS INT;
DECLARE @nextScheduledDate AS DATETIME2(6);
DECLARE @nextRotaCycle AS INT;

DECLARE db_cursor CURSOR FOR
SELECT taskFK, scheduledDate, rotaCycle
FROM cil.schedule 
LEFT JOIN cil.task ON cil.schedule.taskFK=cil.task.id
WHERE completionDate=@myCompletionDate
AND equipFK=@equipID;

OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @nextTaskID, @nextScheduledDate, @nextRotaCycle;

WHILE @@FETCH_STATUS = 0  
BEGIN  
   --Do stuff with scalar values
   INSERT INTO cil.schedule (taskFK, scheduledDate, rotaCycle)
        VALUES(@nextTaskID
            ,DATEADD(dd, @nextRotaCycle, @nextScheduledDate)
            ,@nextRotaCycle)

   FETCH NEXT FROM db_cursor INTO @nextTaskID, @nextScheduledDate, 
@nextRotaCycle;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;

GO