如果我想在结果集的每一行上进行多次操作

时间:2011-04-28 06:24:46

标签: sql stored-procedures

如果我想对结果集的每一行进行多次操作,我是否必须使用循环或游标。有没有其他有效或方便的方法呢?我正在编写一个长存储过程,我使用了一个只读光标用于外部循环。我还需要一些循环内部循环。 (我是新的程序员,我的英语不好,我希望有人可以帮助我。)

1 个答案:

答案 0 :(得分:1)

在你的问题中仍然没有足够的信息来给出一个好的答案。我将分享一些可能“足够”的代码,以帮助您查看重新构建问题的一种方法以避免游标/循环。假设我们有一个表,我们将其用作队列(称为队列)。对于这个简单的例子,我们所存储的是一个值(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)。 / p>

因此,让我们创建一些要处理的示例行:

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匹配,但不保证。

以上是我对How Can I avoid using Cursor for implementing this pseudo code - SQL Server的回答的重新处理,其中包括在更新原始表之前进一步插入第二个表。