views:

96

answers:

4

Hi

I have a requirement like this: I have to select a certain number of records from an Oracle table using a stored procedure. I will capture the entire resultset in ref cursors, but at the same time I have to update a flag in the selected records ( the ones stored in ref cursors).

So I want to know whether this is possible in stored procedure. If yes, then what do I have to use e.g. triggers?

Thanks in advance

+1  A: 

A cursor doesn't "capture" or "store" anything. To store something, use a PL/SQL table. Probably the closest thing to what you want to do:

DECLARE
  type t_foobar is table of foobar;
  v_foobar t_foobar;
BEGIN
  UPDATE foobar SET flag=1 WHERE foo=bar AND flag=0 AND rowum<=10;
  SELECT * FROM foobar BULK SELECT INTO v_foobar WHERE flag=1;
  UPDATE foobar SET flag=2 WHERE flag=1;
  COMMIT;
  /* process v_foobar here */
END;

I'm doing two UPDATEs here so that in a concurrent environment, every session selects und updates different rows. (E.g. for a airplane seat reservation system)

ammoQ
I have one doubt, will this concept of rownum work if the first 10 rows are already marked and need not to be selected
Vivek
Yes, that's what the `AND flag=0` is for. It returns only rows that have not been handled. Make sure to put an index on that flag-column, and think about error handling. If your processing fails in the provided version, you are not going to find the failed rows any more...
Peter Lang
Vivek: the rownum filter is applied by Oracle AFTER every other filter, so don't worry.
ammoQ
+1  A: 

It sounds like you are trying to ensure multiple processes do not select the same rows?

SELECT FOR UPDATE NO WAIT might be your best option.
http://download.oracle.com/docs/cd/E11882%5F01/appdev.112/e10472/static.htm#CIHHIIID

While that's 11.2 it will work for earlier versions of Oracle, like 10g.

David
A: 

Ref cursors are non-modifiable, as they exist only in memory. They are a reference, as indicated by the name. You will have to perform updates separately.

Adam Hawkes
Hi All,again explaining my requirements:I have a table which contains several thousand of records. I have to process all those records, but i cannot process all the records at same time, i can only process 1000 records at a time. So i am using a stored procedure and calling the same in a loop. Now to avoid the duplicate records to be fetched again, i am updating a flag for all those records which i have selected in one iteration, that's why i have to update the all of the records which have been selected in a stored procedure.
Vivek
+1  A: 

Firstly you will not "capture the entire resultset in ref cursors", a ref cursor is a pointer to a result set. In effect, what you are returning is a query that will (or technically MAY) by executed by whatever receives it.

I'd forget the ref cursor and go with a pipelined table function. That way the procedure can process the records (ie flag them as updated) as it returns them to the caller.

Gary