В вашем вопросе все еще недостаточно информации, чтобы дать хороший ответ. Я поделюсь некоторым кодом, который может быть «адекватным», чтобы помочь вам увидеть один из способов переадресации вопроса, чтобы избежать курсоров / циклов. Скажем, у нас есть таблица, которую мы используем в качестве очереди (называемой очередью). В этом простом примере все, что мы храним, это значение (Action), которое мы хотим вставить позже в другую таблицу (называемую Target):
create table Queue (
QueueID int IDENTITY(1,1) not null,
Action varchar(10) not null,
Processed bit not null,
TargetID int null,
constraint PK_Queue PRIMARY KEY (QueueID),
constraint CK_Queue_Processed CHECK ( Processed = 0 or TargetID is not null)
)
go
create table Target (
TargetID int IDENTITY(1,1) not null,
Action varchar(10) not null,
constraint PK_Target PRIMARY KEY (TargetID)
)
Обратите внимание, что после обработки элемента из таблицы очереди мы хотим пометить его как обработанный (Processed = 1) и узнать, какую строку мы в конечном итоге вставили в целевую таблицу (TargetID).
Итак, давайте создадим несколько строк для обработки:
insert into Queue(Action,Processed)
select 'abc',0 union all
select 'def',0 union all
select 'ghi',0
А теперь мы обработаем эту очередь, сначала вставив строки в целевую таблицу, а затем соответствующим образом обновим таблицу очередей:
declare @Inter table (QueueID int not null,TargetID int not null)
;merge into Target using (select QueueID,Action from Queue where Processed=0) Queue
on 1=0
when not matched then insert (Action) values (Action)
output Queue.QueueID,inserted.TargetID into @Inter (QueueID,TargetID);
update q
set
Processed = 1,
TargetID = i.TargetID
from
Queue q
inner join
@Inter i
on
q.QueueID = i.QueueID
Мы могли бы использовать более простое выражение insert
(вместо merge
), если бы мы вставляли в целевую таблицу достаточно информации (например, QueueID
), чтобы мы могли извлечь все, что нам нужно, в @Inter
таблица из inserted
псевдо таблицы.
И, наконец, мы проверяем обе таблицы, чтобы убедиться, что они работают так, как мы ожидали:
select * from Queue
select * from Target
На моем компьютере идентификаторы TargetID, назначенные строкам, соответствуют идентификаторам QueueID, но это не гарантируется.
Выше приведен доработка моего ответа на Как можно избежать использования курсора для реализации этого псевдокода - SQL Server , который включал выполнение дополнительной вставки во вторую таблицу перед обновлением исходной таблицы .