For Oracle support & training call (800) 766-1884
Free Oracle Tips

Home
Oracle Tips
Oracle Code Depot
Oracle Monitoring
Oracle Consulting
Oracle Training
Oracle News
Oracle Forum
Oracle Support





 

Free Oracle Tips

image

 
HTML Text

Free Oracle App Server Tips

image

 
HTML Text


Privacy Policy

Redneck

Dress Code

Oracle tuning

Oracle training

Oracle support

Remote Oracle


 

   
  Oracle Tips by Burleson

Cursor For Update

A SELECT statement is a read only operation to the database and the Oracle database never blocks a read.  Even if there are locks on rows, the database will allow a statement to read those rows (subject to the requirement to maintain a consistent view).  Locks are placed on rows when they have been changed and a commit/rollback has not yet ended the transaction.  Until the user changing the row has ended the transaction, the lock remains and no other user can make changes to the locked data. 

Normally, you update, insert, or delete information using standard SQL statements.

begin
  insert into store
     values (select * from pubs.new_store);
end;

Sometimes you will want to select and lock the data so that you restrict anyone else from making changes to the data until you are finished.  To retrieve and lock the data we use the CURSOR FORUPDATE syntax. 

The example below has a lot of new PL/SQL constructs for us to examine.  The function of this code is to update the quantity column in the sales table for every order for store_key ‘S101’.  Let’s just say the author bribed us to increase his sales record.

SQL> declare
  2    cursor c12 is
  3      select store_key
  4      from sales
  5      for update of quantity;
  6  begin
  7    for r_c12 in c12 loop
  8      if r_c12.store_key = 'S101' then
  9        update sales
 10        set quantity= quantity+1
 11        where current of c12;
 12      end if;
 13    end loop;
 14  end;
 15  /

The cursor is declared using the FOR UPDATE clause and the quantity column is identified as the item that will be updated.  At line 7 the database opens the cursor which locks all the rows in the sales table.  An IF/THEN statement is used to identify the rows (orders) that belong to the store with ‘S101’ as it’s key.  Those rows are then updated in lines 9 through 11. 

Notice that lines 9 through 11 are actually one line of code.  The UPDATE WHERE CURRENT OF clauseautomatically updates the row that the cursor is currently using at that time.  Because the update SQL does not have to relocate the row to update, it is very fast.  At the end of the PL/SQL block, all the rows selected by the cursor are still locked (not just the changed rows).  The transaction stays open and the locks are held until a rollback or commit is issued.

Notice that cursor c12 locks all the rows in the sales table because it will update the quantity column.  This cursor could have been defined as the cursor below with the same effect.

declare
  cursor c12 is
    select store_key
    from sales
    for update;
begin

If the cursor will join tables, then all the rows returned by the cursor in both tables are locked.

declare
  cursor c12 is
    select author_last_name, book_title
    from author join book_author using (author_key)
                join book        using (book_key)
    for update;
begin

Here the cursor locks all the rows in the author table, the book_author table and the book table.  This is because the cursor returns all the rows in each of the three tables.   If the intent is to update the book_title column in the book table, the cursor can indicate that as shown in the example below.

declare
  cursor c12 is
   select author_last_name
    from author join book_author using (author_key)
                join book        using (book_key)
    for update of book_title;
begin

Now the database will only lock the rows in the book table because the cursor indicates that although it will retrieve more data, it will only update the book table.  This is an important point.  The database will keep all the rows locked until the transaction ends, not the cursor is closed.  As the programmer, you want to lock as little data in the database as possible.  Always specify the columns to update in the cursor definition to reduce unnecessary row locking.

Here are some important points to remember about the FOR UPDATE clause:

  • Lock as few rows as possible.  Locks reduce concurrency and cause waits, slowing-down your processing.

  • Even though the cursor indicates that it is going to change some data, it is not required to change any values.

  • Even if the cursor identifies a column to update (such as book_title in the above example) it can still update other columns or tables.  In this case, the updates may be blocked by locks held by other users.

  • The locks remain until the end of the transaction (Commit or Rollback), not the closing of the cursor.

  • If another transaction has locks on the data, the cursor open will wait (block) on those locks.  There is no restriction on the time the cursor will wait for the locks to be released.  The NOWAIT clause can be appended to the cursor definition to tell it to return immediately (without opening the cursor) if there are already locks on the data.

  • The WHERE CURRENT OF clause can be used for updates or deletes.  It does not make sense to insert a row at the current cursor location.

  • The CURSOR FORUPDATE using the WHERE CURRENT OF clause is the fastest way to update data.  The cursor will use the rowid to perform the update (or delete) which is the fastest way to locate a specific row in an Oracle database table. 

Cursors can also be defined as variables.  These variables are known as REF CURSORS because the variable references the actual cursor.


The above book excerpt is from:

Easy Oracle PL/SQL Programming

Get Started Fast with Working PL/SQL Code Examples

ISBN 0-9759135-7-3   

John Garmany 

http://www.rampant-books.com/book_2005_1_easy_plsql.htm


For more details and scripts, see my new book " Oracle Tuning: The Definitive Reference", over 900 pages of BC's favorite tuning tips & scripts. 

You can buy it direct from the publisher for 30%-off and get instant access to the code depot.

   
  
 

 
 
 
 
Oracle performance tuning software
 
 

 

 
 
 
Oracle performance Tuning 10g reference poster
 
 
 
Oracle training in Linux commands
 
Oracle training Excel
 
Oracle training & performance tuning books
 

 

Fast-Track Oracle Support
PO Box 511
Kittrell, NC 27544


Email BC: