if I want to make Multiple operation on each row of a resultset
if I want to make Multiple operation on each row of a result set, do I must use loop or cursor. Is there any other effective or convenience way to do that? I am writing a long stored procedure, I have used a readonly cursor for the outside loop.I also need some loop inside loop. (I am new pr开发者_JAVA百科ogrammer, and my english is not good,I hope some one can help me.)
There's still not enough information in your question to give a good answer. I'll share some code that may be "adequate", to help you see one way of re-casting a question to avoid cursors/loops. Say we have a table which we're using as a queue (called Queue). For this simple example, all we're storing is a value (Action) that we want inserted later into another table (called 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)
)
Note that, once an item has been processed from the queue table, we want to mark it as having been processed (Processed=1) and we want to know which row we eventually inserted into the target table (TargetID).
So, let's create some sample rows to process:
insert into Queue(Action,Processed)
select 'abc',0 union all
select 'def',0 union all
select 'ghi',0
And now, we'll process this queue, first inserting rows into the target table, and then updating the queue table appropriately:
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
We could have used a simpler insert
statement (rather than the merge
), if we were inserting enough information into the target table (e.g. QueueID
) such that we could retrieve everything we need in the @Inter
table from the inserted
pseudo table.
And finally, we check both tables to ensure that it's worked as we expected:
select * from Queue
select * from Target
On my machine, the TargetIDs assigned to the rows matched the QueueIDs, but that is not guaranteed.
The above is a re-working of my answer to How Can I avoid using Cursor for implementing this pseudo code - SQL Server, which included performing a further insert into a second table before updating the original table.
精彩评论