ITPub博客

首页 > Linux操作系统 > Linux操作系统 > SELECT FOR UPDATE Cursors

SELECT FOR UPDATE Cursors

原创 Linux操作系统 作者:susie0409 时间:2010-04-12 21:10:00 0 删除 编辑
You use SELECT FOR UPDATE cursors for updating the rows retrieved by a cursor. This is often required when there's a need to modify each row retrieved by a cursor without having to refetch that row. More often, SELECT FOR UPDATE cursors are required to update a column of the table defined in the cursor SELECT using a complex formula.

Defining a SELECT FOR UPDATE Cursor

Add a Note HereA SELECT FOR UPDATE cursor is defined using the FOR UPDATE OF clause in the cursor SELECT statement, as follows:

Add a Note Here

DECLARE
     CURSOR csr_1 IS
           SELECT * FROM sec_hrc_tab FOR UPDATE OF hrc_descr;
BEGIN
     /* ... Open the cursor and process the resultset ... */
    null;
END;
/
Note 

Add a Note HereNotice how the column name to be updated is specified in the FOR UPDATE OF clause. If no column name is specified in the FOR UPDATE OF clause, any column of the underlying cursor table can be modified.

Using a SELECT FOR UPDATE Cursor

Add a Note HereOnce you've defined a SELECT FOR UPDATE cursor, you use the WHERE CURRENT OF clause to process the rows returned by it. You can use this clause in an UPDATE or DELETE statement. It has the following syntax:

Add a Note Here
WHERE CURRENT of cursor_name;

Add a Note Herewhere cursor_name is the name of the cursor defined with a FOR UPDATE clause.

Add a Note HereThe following is a complete example of using SELECT FOR UPDATE cursors. I use the sec_hrc_tab table to demonstrate this. First, this table is populated using an INSERT statement as follows:

Add a Note Here
BEGIN
     INSERT INTO sec_hrc_tab
         SELECT * FROM hrc_tab;
     COMMIT;
END;
/

Add a Note HereThe output can be verified as follows:

Add a Note Here
SQL> select * from sec_hrc_tab;

  HRC_CODE HRC_DESCR
----- -------------
           1 CEO/COO
           2 VP
           3 Director
           4 Manager
           5 Analyst

Add a Note HereThen I define a SELECT FOR UPDATE cursor and use the WHERE CURRENT OF clause to update the rows retrieved by this cursor in a particular fashion. Here's the program for this:

Add a Note Here
DECLARE
       CURSOR csr_1 IS
             SELECT * FROM sec_hrc_tab FOR UPDATE OF hrc_descr;
             v_hrc_descr VARCHAR2(20);
BEGIN
     FOR idx IN csr_1 LOOP
             v_hrc_descr := UPPER(idx.hrc_descr);
             UPDATE sec_hrc_tab
              SET         hrc_descr = v_hrc_descr
              WHERE CURRENT OF csr_1;
     END LOOP;
     COMMIT;
END;
/

Add a Note HereThis program updates the hrc_descr column of each row retrieved by csr_1 with its value converted to uppercase. The output can be verified as follows:

Add a Note HereThe mechanism of SELECT FOR UPDATE cursors works as follows:

  1. Add a Note HereThe SELECT FOR UPDATE cursor puts a lock on the rows retrieved by the cursor. If it's unable to obtain a lock because some other session has placed a lock on the specific rows, it waits until it can get a lock. A COMMIT or ROLLBACK in the corresponding session frees the locks held by other sessions.

  2. Add a Note HereFor each row identified by the cursor, the cursor updates the specified column of that row. That is, it keeps track of the current row and updates it, and then fetches the subsequent row and updates it. It does this without scanning the same table again. This is unlike an ordinary UPDATE or DELETE statement inside the loop, where the cursor scans the updated table again to determine the current row to be modified.

Add a Note HereAlthough you could achieve the same function by using a simple UPDATE statement, this example is meant to illustrate the use of SELECT FOR UPDATE cursors.

Add a Note HereTo use WHERE CURRENT OF, you have to declare the cursor using FOR UPDATE. The reverse is not true. That is, you can use a SELECT FOR UPDATE cursor to modify the rows without using the WHERE CURRENT OF clause. Then, you have to update or delete the cursor rows using the primary key.

Add a Note HereA SELECT FOR UPDATE cursor offers two important advantages: Namely, it locks the rows after opening the cursor and the resultset rows are identified for update, and it eliminates a second fetch of the rows for doing the update and preserves the current row by the WHERE CURRENT OF clause.

Add a Note HereYou have to do a COMMIT outside of the cursor loop when you use WHERE CURRENT OF in processing the rows of a SELECT FOR UPDATE cursor. This is because a COMMIT releases the lock on the rows that the SELECT FOR UPDATE has put a lock on, and this causes a subsequent fetch to fail.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15225049/viewspace-659508/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2009-09-30

  • 博文量
    115
  • 访问量
    305730