Select for update gives wrong results. Is it a bug?

Hi,
Select for update gives wrong results. Is it a bug?
CREATE TABLE TaxIds
TaxId NUMBER(6) NOT NULL,
LocationId NUMBER(3) NOT NULL,
Status NUMBER(1)
PARTITION BY LIST (LocationId)
PARTITION P111 VALUES (111),
PARTITION P222 VALUES (222),
PARTITION P333 VALUES (333)
ALTER TABLE TaxIds ADD ( CONSTRAINT PK_TaxIds PRIMARY KEY (TaxId));
CREATE INDEX NI_TaxIdsStatus ON TaxIds ( NVL(Status,0) ) LOCAL;
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100101, 111, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100102, 111, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100103, 111, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100104, 111, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200101, 222, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200102, 222, NULL);
Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200103, 222, NULL);
--Session_1 return TAXID=100101
select TAXID from TAXIDS where LOCATIONID=111 and NVL(STATUS,0)=0 AND rownum=1 for update
--Session_2 waits commit
select TAXID from TAXIDS where LOCATIONID=111 and NVL(STATUS,0)=0 AND rownum=1 for update
--Session_1
update TAXIDS set STATUS=1 Where TaxId=100101;
commit;
--Session_2 return 100101 opps!?
--Session_1 return TAXID=100102
select TAXID, STATUS from TAXIDS where LOCATIONID=111 and NVL(STATUS,0)=0 AND rownum=1 for update
--Session_2 waits commit
select TAXID, STATUS from TAXIDS where LOCATIONID=111 and NVL(STATUS,0)=0 AND rownum=1 for update
--Session_1
update TAXIDS set STATUS=1 Where TaxId=100102;
commit;
--Session_2 return 100103                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

This is a bug. Got to be a bug.
This should be nothing to do with indeterminate results from ROWNUM, and nothing to do with read consistency at the point of statement start time in session2., surely.
Session 2 should never return 100101 once the lock from session 1 is released.
The SELECT FOR UPDATE should restart and 100101 should not be selected as it does not meet the criteria of the select.
A statement restart should ensure this.
A number of demos highlight this.
Firstly, recall the original observation in the original test case.
Setup
SQL> DROP TABLE taxids;
Table dropped.
SQL> 
SQL> CREATE TABLE TaxIds
  2  (TaxId NUMBER(6) NOT NULL,
  3   LocationId NUMBER(3) NOT NULL,
  4   Status NUMBER(1))
  5  PARTITION BY LIST (LocationId)
  6  (PARTITION P111 VALUES (111),
  7   PARTITION P222 VALUES (222),
  8   PARTITION P333 VALUES (333));
Table created.
SQL>
SQL> ALTER TABLE TaxIds ADD ( CONSTRAINT PK_TaxIds PRIMARY KEY (TaxId));
Table altered.
SQL>
SQL> CREATE INDEX NI_TaxIdsStatus ON TaxIds ( NVL(Status,0) ) LOCAL;
Index created.
SQL>
SQL>
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100101, 111, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100102, 111, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100103, 111, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (100104, 111, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200101, 222, NULL);
1 row created.
SQL> Insert into TAXIDS (TAXID, LOCATIONID, STATUS) Values (200102, 222, NULL);
1 row created.
SQL> commit;
Commit complete.
SQL> Original observation:
Session1>SELECT taxid
  2  FROM   taxids
  3  WHERE  locationid    = 111
  4  AND    NVL(STATUS,0) = 0
  5  AND    ROWNUM        = 1
  6  FOR UPDATE;
     TAXID
    100101
Session1>
--> Session 2 with same statement hangs until
Session1>BEGIN
  2   UPDATE taxids SET status=1 WHERE taxid=100101;
  3   COMMIT;
  4  END;
  5  /
PL/SQL procedure successfully completed.
Session1>
--> At which point, Session 2 returns
Session2>SELECT taxid
  2  FROM   taxids
  3  WHERE  locationid    = 111
  4  AND    NVL(STATUS,0) = 0
  5  AND    ROWNUM        = 1
  6  FOR UPDATE;
     TAXID
    100101
Session2>There's no way that session 2 should have returned 100101. That is the point of FOR UPDATE. It completely reintroduces the lost UPDATE scenario.
Secondly, what happens if we drop the index.
Let's reset the data and drop the index:
Session1>UPDATE taxids SET status=0 where taxid=100101;
1 row updated.
Session1>commit;
Commit complete.
Session1>drop index NI_TaxIdsStatus;
Index dropped.
Session1>Then try again:
Session1>SELECT taxid
  2  FROM   taxids
  3  WHERE  locationid    = 111
  4  AND    NVL(STATUS,0) = 0
  5  AND    ROWNUM        = 1
  6  FOR UPDATE;
     TAXID
    100101
Session1>
--> Session 2 hangs again until
Session1>BEGIN
  2   UPDATE taxids SET status=1 WHERE taxid=100101;
  3   COMMIT;
  4  END;
  5  /
PL/SQL procedure successfully completed.
Session1>
--> At which point in session 2:
Session2>SELECT taxid
  2  FROM   taxids
  3  WHERE  locationid    = 111
  4  AND    NVL(STATUS,0) = 0
  5  AND    ROWNUM        = 1
  6  FOR UPDATE;
     TAXID
    100102
Session2>Proves nothing, Non-deterministic ROWNUM you say.
Then let's reset, recreate the index and explicity ask then for row 100101.
It should give the same result as the ROWNUM query without any doubts over the ROWNUM, etc.
If the original behaviour was correct, session 2 should also be able to get 100101:
Session1>SELECT taxid
  2  FROM   taxids
  3  WHERE  locationid    = 111
  4  AND    NVL(STATUS,0) = 0
  5  AND    taxid         = 100101
  6  FOR UPDATE;
     TAXID
    100101
Session1>
--> same statement hangs in session 2 until
Session1>BEGIN
  2   UPDATE taxids SET status=1 WHERE taxid=100101;
  3   COMMIT;
  4  END;
  5  /
PL/SQL procedure successfully completed.
Session1>
--> so session 2 stops being blocked and:
Session2>SELECT taxid
  2  FROM   taxids
  3  WHERE  locationid    = 111
  4  AND    NVL(STATUS,0) = 0
  5  AND    taxid         = 100101
  6  FOR UPDATE;
no rows selected
Session2>Of course, this is how it should happen, surely?
Just to double check, let's reintroduce ROWNUM but force the order by to show it's not about read consistency at the start of the statement - restart should prevent it.
(reset, then)
Session1> select t.taxid
  2   from
  3    (select taxid, rowid rd
  4      from   taxids
  5      where  locationid = 111
  6      and    nvl(status,0) = 0
  7      order by taxid) x
  8   ,  taxids t
  9   where t.rowid = x.rd
10   and   rownum = 1
11   for update of t.status;
     TAXID
    100101
Session1>
--> Yes, session 2 hangs until...
Session1>BEGIN
  2   UPDATE taxids SET status=1 WHERE taxid=100101;
  3   COMMIT;
  4  END;
  5  /
PL/SQL procedure successfully completed.
Session1>
--> and then
Session2> select t.taxid
  2   from
  3    (select taxid, rowid rd
  4      from   taxids
  5      where  locationid = 111
  6      and    nvl(status,0) = 0
  7      order by taxid) x
  8   ,  taxids t
  9   where t.rowid = x.rd
10   and   rownum = 1
11   for update of t.status;
     TAXID
    100102
Session2>Session 2 should never be allowed to get 100101 once the lock is released.
This is a bug.
The worrying thing is that I can reproduce in 9.2.0.8 and 11.2.0.2.

Similar Messages

  • JDBC SELECT FOR UPDATE

    I'm trying to issue a SELECT ... FROM ... FOR UPDATE, and under specific verified conditions runs an UPDATE (where the current is positioned!).
    The error code I get is:
    ORA-01002: Fetch out of sequence.
    Here you are my code:
    /////////////////////START
    import java.sql.*;
    import oracle.jdbc.*;
    import oracle.sql.*;
    public class SelForUpdDin{
    static{
         try{
              Class.forName("oracle.jdbc.driver.OracleDriver");
         catch(Exception e){e.printStackTrace();}
    // Queries and cursor name
    public static void main (java.lang.String[] args){
    String cursorName = null;
    int codice = 0;
    String cognome = null;
    String job = null;
    int manager = 0;
    java.sql.Date dataAss = null;
    int salario = 0;
    int commissioni = 0;
    int reparto = 0;
    String rowid = null;
    String sqlSelect = "SELECT empno, ename, "+
    "job, mgr, hiredate, sal, comm, deptno, ROWID "+
    "FROM scott.emp FOR UPDATE";
    String sqlUpdate = "UPDATE scott.emp SET comm = ? WHERE ROWID = ? ";
    try {
    Connection con = DriverManager.getConnection("jdbc:Oracle:oci8:@","system","manager");
    // Esecuzione della SELECT e produzione del RESULT SET
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(sqlSelect);
    PreparedStatement ps = con.prepareStatement(sqlUpdate);
    while (rs.next()) {
    codice = rs.getInt(1);
    cognome = rs.getString(2);
    job = rs.getString(3);
    manager = rs.getInt(4);
    dataAss = rs.getDate(5);
    salario = rs.getInt(6);
    commissioni = rs.getInt(7);
    reparto = rs.getInt(8);
    rowid = rs.getString(9);
    // Applicazione della business logic
    if (reparto == 30)
    { System.out.println (cognome + " in dept= "+ reparto +
    " with salary=" + salario + " has a commission= " +
    commissioni);
    int newcomm = 5555;
    ps.setInt(1,newcomm);
    ps.setString(2,rowid);
    ps.executeUpdate();
    else
    { System.out.println (cognome + " in dept= "+ reparto +
    " with salary=" + salario + " has a commission= " + commissioni);
    } // if - else
    } // end while
    rs.close();
    ps.close();
    stmt.close();
    catch(Exception e)
    e.printStackTrace();
    } // end main()
    } // end class
    //PS.
    //Many thanks to Bachar and Elangovan that ansewerd me to my previous posting and addressed me towards the right solution

    Hi
    The documentation gives following explanation for the error :
    ORA-01002 fetch out of sequence
    Cause: In a host language program, a FETCH call was issued out of sequence. A successful parse-and-execute call must be issued before a fetch. This can occur if an attempt was made to FETCH from an active set after all records have been fetched. This may be caused by fetching from a SELECT FOR UPDATE cursor after a commit. A PL/SQL cursor loop implicitly does fetches and may also cause this error.
    Action: Parse and execute a SQL statement before attempting to fetch the data.
    In your program you should set auto commit to false as follows :
    con.setAutoCommit(false);
    Do this before executing the SELECT FOR UPDATE sql query.
    At the end of program you can commit to save the updations as follows:
    con.commit();
    This should solve the problem.
    Chandar

  • Select for update on stateless connections

    i have read that using select for update for a web application will not work specially if the stateless connection are used , and the best way to make sure that the column you are reading was not changed is to use the time stamp approach and not select for update?? i am right

    Not entirely correct.
    A connection/session to Oracle has state. There is no such thing as a stateless Oracle connection.
    The stateless connection is from the web browser to the web server. It makes a connection. Asks for a page (GET, PUT or POST typically). It gets a response from the web server. It closes that connection.
    When the web server response, it opens a (stateful) connection to Oracle. Or it re-uses an existing (stateful) Oracle connection (now idle after having serviced another web browser/web server request).
    The problem with pessimistic locking (e.g. SELECT FOR UPDATE) is that the very same (stateful) Oracle session will either
    a) be closed when a response is send to the web browser
    b) be used for another totally different web browser
    Thus any locks made will either be lost (option a) or will get used by the wrong web browser (option b).
    A method is therefore needed to make the lock spans different Oracle (stateful) sessions. Web browser selects rows to update using Oracle session 101 at Time 1. Web browser submits updated rows and a commit using Oracle session 142 at Time 2.
    The "best way" to handle optimistic locking is likely using the Oracle System Change Number (SCN). This represents the "current version" of the rows.
    So at Time 1, via Session 101, you give the web browser a 100 rows to update - together with the SCN that says the current version of the rows are v1.2.0.1.
    At Time 2, using Session 142, the web browser submits its changes for those 100 rows. Together with the SCN v1.2.0.1.
    The SQL UPDATE issues the update statement - but adds the SCN version criteria. If the UPDATE fails to update all 100 rows, it means that some of the rows no longer exist, or that some rows have a new version number (was changed in the meantime).
    In this case, the UPDATE is rolled back and an exception raised to tell the web browser that some (or all) of those 100 rows have been changed in the meantime.
    Refer to the [url http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/pseudocolumns007.htm#BABFAFIC]Oracle® Database SQL Reference for details.

  • "All of the Playlists Selected for Updating No Longer Exist"

    My family has 2 ipod shuffles. After purchasing a Nano recently, I inserted the cd that came with it. Apparently the existing iTunes software was removed and reinstalled. At any rate, the library still shows all the original songs, but when the Nano is plugged in, iTunes immediately gives a prompt stating "Songs on the iPod *** cannot be updated because all of the playlists selected for updating no longer exist." The library is there, the playlists that were there are there, and I can play the songs on my cpu. Is there anything I can do besides completely uninstalling everything and starting over?
    iPod Nano   Windows XP Pro  

    This user tip should help you sort out your missing playlist problem: Hudgie - iPod cannot sync because one or more playlists are missing

  • Rogue implicit SELECT FOR UPDATE statement in forms 9i  9.0.4.0.19

    all,
    out of 200 production forms, one form occasionally and incorrectly "selects for update" an entire 3 million row table, during an update transaction. this creates 100+ archive logs.
    we cannot repeat the event via testing. but the rogue select statement has been captured from SGA and is listed below. its plain to see that somehow the where clause is truncated to a W, and is then used as a table alias, resulting in the entire table being locked.
    has anyone seen anything like this?
    SELECT ROWID,DISTRIBUTION_PARTY,DISTRIBUTION_PARTY_NAME,CORRESPOND_SEQ_NUM,DISTRIBUTION_SEQ_NUM,VENDOR_NUM,DEPENDENT_SEQ_NUM,INTERNAL_ATTORNEY_USER_NAME,MAIL_LOC,ORIGINAL_FLAG
    FROM CLAIM_DISTRIBUTION_DATA W
    FOR UPDATE OF DISTRIBUTION_PARTY NOWAIT

    Find out where this select statement is issued from first of all. Is it in your code or is it issued implicitely by Forms? Since it has rowid I assume it is an implicit Forms call.
    Do you use on-update triggers any where in this form? on-lock?

  • Lock Cascade With Select for UPDATE

    If I had a employee table and a phone table with a parent/child relationship and a primary key constraint on the employee table-will issuing a select for update on the employee also lock the corresponding child rows on the phone table ?
    If not how can I bring this about ?

    You only need two sessions:
    First session: Issue the 'select for update'
    statements for the row(s) in both tables, don't
    rollback or commit
    Second session: try to update a row that you tried to
    lock in the first session (with NOWAIT).
    Thanks. I can try this definitely. A basic question.
    You are asking me to do a join on both the tables right ?
    Not two individual SQL statements ?
    Updating the primary key is known as a Bad Idea (tm).
    The key should never be touched because it should be
    meaningless. When you have a column that holds 'real'
    information it is no candidate for a primary key.
    Rgds,
    GuidoYes I am aware of that. I was just wondering what is the meaning behind this statement from this link ?
    http://www.akadia.com/services/ora_locks_survival_guide.html
    And the exact phrase from that link under the section Referential Integrity Locks (RI Locks)
    "RI constraints are validated by the database via a simple SELECT from the dependent (parent) table in question-very simple, very straightforward. If a row is deleted or a primary key is modified within the parent table, all associated child tables need to be scanned to make sure no orphaned records will result. "
    Thanks again.

  • Deadlock detected during SELECT FOR UPDATE - an application error?

    I have a general question about how Oracle prevents deadlocks from affecting
    applications: do I need to build support into the application for handling
    deadlocks when they occur in this particular scenario, or should Oracle handle
    this for me? I'd like to know whether this is "normal" behavior for an Oracle
    application, or if there is an underlying problem. Consider the following situation:
    Two sessions issue individual SELECT FOR UPDATE queries. Each query locates
    records in the table using a different index. These indexes point to rows in a
    different order from each other, meaning that a deadlock will occur if the two
    statement execute simultaneously.
    For illustrative purposes, consider these rows in a hypothetical table.
    ALPHABET
    alpha
    bravo
    charlie
    delta
    echo
    foxtrot
    golf
    hotel
    Index A results in traversing the table in ascending alphabetical order; index
    B, descending. If two SELECT FOR UPDATE statements concurrently execute on this
    table--one with an ascending order execution path and one in descending order--
    the two processes will deadlock at the point where they meet. If Session A
    locks alpha, bravo, charlie, and delta, while Session B locks hotel, golf,
    foxtrot, and echo, then neither process can proceed. A needs to lock echo, and
    B needs to lock delta, but one cannot continue until the other releases its
    locks.
    This execution path can be encouraged using hints. Executing queries similar to these on larger tables will generate the "collision" as described above.
    -- Session A
    select /*+ index_asc (customer) */
    from customer
    where gender = 'M'
    for update;
    -- Session B
    select /*+ index_desc (customer) */
    from customer
    where gender = 'M'
    for update;
    Oracle will recognize that both sessions are in a stand-off, and it will roll
    back the work performed by one of the two sessions to break the deadlock.
    My question pivots on whether or not, in this situation, the deadlock gets
    reported back to the application executing the queries as an ORA-00060. If
    these are the ONLY queries executed during these sessions, I would think that
    Oracle would rollback the locking performed in one of the SELECT FOR UPDATE
    statements. If I understand correctly,
    (1) Oracle silently rolls back and replays work performed by UPDATE statements
    when a deadlock situation occurs within the scope of the update statement,
    and
    (2) A SELECT FOR UPDATE statement causes Oracle, at the point in time the cursor
    is opened, to lock all rows matching the WHERE clause.
    If this is the case, then should I expect Oracle to produce an ORA-00060
    deadlock detection error for two SELECT FOR UPDATE statements?
    I would think that, for deadlock situations completely within Oracle's control,
    this should be perceived to the application invoking the SELECT FOR UPDATE
    statements as regular blocking. Since the query execution plans are the sole
    reason for this deadlock situation, I think that Oracle would handle the
    situation gracefully (like it does for UPDATE, as referenced in (1)).
    Notice, from the trace file below, that the waits appear to be from row locking,
    and not from an artificial deadlock (e.g. ITL contention).
    Oracle8i Enterprise Edition Release 8.1.7.4.0 - 64bit Production
    With the Partitioning option
    DEADLOCK DETECTED
    Current SQL statement for this session:
    SELECT XXX FROM YYY WHERE ZZZ LIKE 'AAA%' FOR UPDATE
    ----- PL/SQL Call Stack -----
    object line object
    handle number name
    58a1f8f18 4 anonymous block
    58a1f8f18 11 anonymous block
    The following deadlock is not an ORACLE error. It is a
    deadlock due to user error in the design of an application
    or from issuing incorrect ad-hoc SQL. The following
    information may aid in determining the deadlock:
    Deadlock graph:
    ---------Blocker(s)-------- ---------Waiter(s)---------
    Resource Name process session holds waits process session holds waits
    TX-002f004b-000412cf 37 26 X 26 44 X
    TX-002e0044-000638b7 26 44 X 37 26 X
    session 26: DID 0001-0025-00000002     session 44: DID 0001-001A-00000002
    session 44: DID 0001-001A-00000002     session 26: DID 0001-0025-00000002
    Rows waited on:
    Session 44: obj - rowid = 0000CE31 - AAANCFAApAAAAGBAAX
    Session 26: obj - rowid = 0000CE33 - AAANCHAArAAAAOmAAM
    Thanks for your insight,
    - Curtis
    (1) "Oracle will silently roll back your update and restart it"
    http://tkyte.blogspot.com/2005/08/something-different-part-i-of-iii.html
    (2) "All rows are locked when you open the cursor, not as they are fetched."
    http://download-east.oracle.com/docs/cd/A87860_01/doc/appdev.817/a77069/05_ora.htm#2170
    Message was edited by:
    Curtis Light

    Thanks for your response. In my example, I used the indexes to force a pair of query execution plans to "collide" somewhere in the table in question by having one query traverse the table via index in an ascending order, and another in descending. This is an artificial scenario for reproducible illustrative purposes, but similar collisions could legitimately occur in real world scenarios (e.g. a full table scan and an index range scan with lookup by ROWID).
    So, with that said, I think it would be unreasonable for Oracle to report the collision as a ORA-00060 every time it occurs because:
    (1) The UPDATE statement handles this situation automatically, and
    (2) An ORA-00060 results in a 100+KB trace file being written out, only rational for truly erroneous situations.
    I agree that, when the application misbehaves and locks rows out of order in separate SQL statements, then Oracle should raise an ORA-00060, as the deadlock is outside of its control. But in this case, the problem occurs with just two individual SQL statements, each within its own transaction.

  • Strange behavior of select for update

    I observed a strange behavior of "select .. for update" statement in binary xml table. Here is the piece of code:
    create table xmltab of XMLType XMLTYPE store as binary xml;
    Table created.
    insert into xmltab values('<x><y>y1</y><z>z1</z></x>');
    1 row created.
    select x.object_value
    from xmltab x
    where extractValue(x.object_value,'/x/y')='y1' and
    extractValue(x.object_value,'/x/z')='z1' ;
    OBJECT_VALUE
    <x>
      <y>y1</y>
      <z>z1</z>
    </x>
    The following query doesn't return any row!!
    select x.object_value
    from xmltab x
    where extractValue(x.object_value,'/x/y')='y1' and
    extractValue(x.object_value,'/x/z')='z1' for update;
    no rows selected
    select x.object_value
    from xmltab x
    where extractValue(x.object_value,'/x/y')='b1' for update;
    OBJECT_VALUE
    <x>
      <y>b1</y>
      <z>z1</z>
    </x>
    select x.object_value
    from xmltab x
    where extractValue(x.object_value,'/x/z')='z1' for update;
    OBJECT_VALUE
    <x>
      <y>b1</y>
      <z>z1</z>
    </x>
    The following one returns correct result !!
    select x.object_value, extractValue(x.object_value,'/x/y'), extractValue(x.object_value,'/x/z')
    from xmltab x
    where extractValue(x.object_value,'/x/y')='b1' and
    extractValue(x.object_value,'/x/z')='z1' ;
    OBJECT_VALUE
    EXTRACTVALUE(X.OBJECT_VALUE,'/x/y')
    EXTRACTVALUE(X.OBJECT_VALUE,'/x/z')
    <x>
      <y>b1</y>
      <z>z1</z>
    </x>
    b1
    c1
    I get expected result for all the cases if the table is created in the following way
    create table xmltab of XMLType;
    Can anyone tell me why does select for update behaves in this strange way for binary xml table?

    Sorry for copy paste problem. b1 should be replaced with y1 and c1 with z1.
    Here is the correct code.
    create table xmltab of XMLType XMLTYPE store as binary xml;
    Table created.
    insert into xmltab values('<x><y>y1</y><z>z1</z></x>');
    1 row created.
    select x.object_value
    from xmltab x
    where extractValue(x.object_value,'/x/y')='y1' and
    extractValue(x.object_value,'/x/z')='z1' ;
    OBJECT_VALUE
    <x>
      <y>y1</y>
      <z>z1</z>
    </x>
    The following query doesn't return any row!!
    select x.object_value
    from xmltab x
    where extractValue(x.object_value,'/x/y')='y1' and
    extractValue(x.object_value,'/x/z')='z1' for update;
    no rows selected
    select x.object_value
    from xmltab x
    where extractValue(x.object_value,'/x/y')='y1' for update;
    OBJECT_VALUE
    <x>
      <y>y1</y>
      <z>z1</z>
    </x>
    select x.object_value
    from xmltab x
    where extractValue(x.object_value,'/x/z')='z1' for update;
    OBJECT_VALUE
    <x>
      <y>y1</y>
      <z>z1</z>
    </x>
    The following one returns correct result !!
    select x.object_value, extractValue(x.object_value,'/x/y'), extractValue(x.object_value,'/x/z')
    from xmltab x
    where extractValue(x.object_value,'/x/y')='y1' and
    extractValue(x.object_value,'/x/z')='z1' ;
    OBJECT_VALUE
    EXTRACTVALUE(X.OBJECT_VALUE,'/x/y')
    EXTRACTVALUE(X.OBJECT_VALUE,'/x/z')
    <x>
      <y>y1</y>
      <z>z1</z>
    </x>
    y1
    z1
    I get expected result for all the cases if the table is created in the following way
    create table xmltab of XMLType;
    Can anyone tell me why does select for update behaves in this strange way for binary xml table?

  • Pros and  cons  of  select  for  update  clause

    hi,
    Can anybody explain what are the
    pros and cons of select for update clause
    11.2.0.1

    As commented, there are no pros versus cons in this case.
    What is important is to understand conceptually what this do and why it would be use.
    Conceptually, a select for update reads and locks row(s). It is known as pessimistic locking.
    Why would you want to do that? Well, you have a fat client (Delphi for example) and multiple users. When userA updates an invoice, you want that invoice row(s) locked and prevent others from making updates at the same time. Without locking, multiple users updating the same invoice will result in existing updated data being overwritten by old data that also has been updated. A situation called lost updates.
    For web based clients that are stateless, pessimistic locking does not work - as the clients do not have state and pessimistic locking requires state. Which means an alternative method to select for update needs to be used to prevent lost updates. This method is called optimistic locking.
    So it is not about pros versus cons. It is about understanding how the feature/technique/approach works and when to use it.. and when it is not suited to use it. All problems are not nails. All solutions are not the large hammer for driving in nails.

  • Performance of using a Select For Update vs a correlated subquery

    I was wondering wether or not it is more effecient to use the
    Select ... For Update (with a cursor etc.) versus a correlated
    subquery.
    I can accomplish the same thing with either however performance
    at our site is an issue.

    Use select for update cursor as that is faster as it updates
    based on the rowid. One thing to keep in mind is that rowid is
    session specific and the rows to be updated get locked so that
    nobody else can update them till the lock is released. I have
    had very good performance results with these cursors.
    Good luck !
    Sudha

  • Database select for update locks ADF

    Hi,
    When a user has initiated an update session in an adf application and locking is optimistic it will acquire a lock on table row using select for update no wait; . But when the user closes a tab the session would not be terminated. Now i know as HTTP is a stateless protocol, we can wait for the timeout and then the lock will be released using a session listener implementation. But if the user instead tries to log in again in a new tab and tries to edit the same record he will receive a message stating that another user already holds a lock on the record which is correct, but is misleading.
    So can we rely on javascript for these scenarios that as soon as the user closes the tab the session should be terminated.
    Here's a snippet
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" ></script>
    <script type="text/javascript">
    var unLoad = function() {
        dojo.io.script.get({
        url:'http://127.0.0.1:7101/myapp/adfAuthentication?logout=true',
        timeout:15000,
      dojo.addOnWindowUnload(unLoad);
    </script>I know this might not work always as it depends on the fact that request might / might not be processed by the server.
    Are there any alternate solutions and also reducing the session timeout is ruled out in my scenario.

    Ramandeep,
    So are there other alternatives or solutionsAlternatives or solutions to what, exactly? As Jobinesh has told you, as long as you use optimistic locking, ADF doesn't acquire database locks except in the context of a transaction that is going to be completed in the current HTTP request. You could obviously force ADF to deviate from this if you called "postChanges" during an HTTP request and leave the transaction hanging, but that would just be wrong in an optimistic locking scenario - the solution would be "don't do that."
    John

  • Select for update that doesn't return any rows

    Are there any odd side-effects that may occur if a select for update that returns no results is never committed? I wouldn't think there are, but I'm not sure if there would be some kind of overhead or unforeseen consequences. This isn't a terribly important question, but it's come up in some coding I've done and I've not been able to find any documentation addressing it.

    A select for update only locks rows that meet the predicate specified in the where clause. So, if the query returns no rows, no rows are locked.
    session1> SELECT * FROM t;
            ID DESCR
             1 Un
             5 One
             2 THIS IS WA
    session1> SELECT * FROM t
      2  WHERE id = 11 FOR UPDATE;
    no rows selectedA second session can update rows in the table
    session2> UPDATE t
      2  SET descr = 'One'
      3  WHERE id = 1;
    1 row updated.John
    Edited by: John Spencer on Jan 7, 2009 1:36 PM
    I just realized that, although you can do updates on the table after the select fo update that returns no rows, you cannot do DDL operations liike a truncate. Unless the session that does the select for update either ends the transaction (i.e. commit or rollback) or ends the session DDL operations will fail.

  • How to SELECT FOR UPDATE with CMP (Oracle)

    The most common database (Oracle) by default uses a scheme that does not fit into any of those isolation levels. A SELECT statement selects data at the start of the transactions, whereas a SELECT ... FOR UPDATE does something quite different. It is essential to do SELECT FOR UPDATEs before updating the row as SELECT does no lock. It's a hack that works well in practice.
    1. Which isolation level is this?
    2. More fundamentally, how an earth is it possible to use this scheme with CMP?! You would have to distinguish load() from loadForUpdate()! Is CMP inconsistent with Oracle?
    This is a pretty big whole in the CMP spec!

    No. thats no goes well.
    Transaction serializable in Oracle uses a optimistic
    concurrency system. And for update is a
    pessimistic concurrency.
    With optimistic: the system is faster but it can fail
    With pessimistic: if doesnt fail (usually;)
    You can solve the proble with many differents systems:
    1. Edit the .xml descriptor files ans change the sql sentences.
    And my prefer one.
    2. Make a new jdbc driver that inherits from the original
    oracledriver.
    The new driver give u in "getConnection()" a new connection class that inherits from the original connection.
    The executestatement and preparestatement adds the
    string "for update" if the stattement was starting by select.
    Configure your container to use the new driver.

  • 0CRM_OPPT_H  (Transaction RSA3 gives wrong result)

    Hi gurus,
    <b>0CRM_OPPT_H  (Transaction RSA3 gives wrong result)
    BBPCRM 4.0
    BW 3.50 version</b>
    I had enhanced the structure "crmt_bw_oppt_h"
    and also written a BADI to populate Opportunity header status.
    But when I run extract checker RSA3 for CRM data,
    I get wrong number of records.
    I am having 95 records for Opportunities header data.
    Data Records / Call = "100"
    Display Extr. Calls = "10"
    Above settings, I am retrieving only 61 records.
    <b>Data Records / Call = "1"
    Display Extr. Calls = "200"
    For the above settings in RSA3,
    I am able to retrieve 95 records correctly.</b>
    The problem is that in RSA1 transaction of BW 3.50 server also,
    61 records are being loaded from CRM server.
    <b>Could this be a Cache memory problem,
    Are any of my BASIS settings a cause for this problem?</b>
    Any help is really appreciated and will be rewarded.
    Thanks,
    Aby Jacob
    ========

    Dear Friends,
    <b>I had to do a small correction in my BADI code.
    I got a solution from Online SAP HELP portal.</b>
    http://help.sap.com/saphelp_nw04/helpdata/en/eb/3e7cf4940e11d295df0000e82de14a/frameset.htm
    Notes on BADI Usage
    ====================
    The instance generated through the factory method should be declared
    as globally as possible or generally be passed as a parameter
    to ensure that the initialization process must be run as rarely as possible
    – just once would be best. In no case should you discard the instance as soon as
    it is generated or repeatedly run the initialization process in a loop.
    Within the adapter class interface,
    required database accesses are buffered locally,
    so that each access is executed once only.
    However, repeated initialization makes
    the buffer useless and dramatically reduces performance.
    Due to the local buffering, you can call Business-Add-In methods
    without having to expect considerable performance restrictions,
    even if no active implementations exist.
    Also, if the definition of the Business-Add-In is filter-dependent,
    a single instance is sufficient.
    However, you should not do without initialization altogether.
    Even if you could call static methods of the implementing
    class of the Business-Add-In implementation without an instance,
    you would lose the benefit of performance improvement through
    the Business-Add-Ins and the possibility of multiple use.
    If you switch the method type in the interface from the static method
    to the instance method at any time in the future,
    many code adjustments are required.
    In addition, you can no longer use default code that is provided.
    <b>Many Thanks to ROBIN
    and the whole SDN team</b>
    Aby Jacob ,,,,,

  • Error message: "playlists selected for updating no longer exist"

    I tried to update my ipod nano and I guess I had deleted a playlist, but since then, I have not been able to update. Every time I try, I get the following message:
    "Cannot be updated because all of the playlists selected for updating no longer exist."
    I haven't been able to highlight which playlists are selected to begin with.
    I read through the manual and thought that maybe rebooting the whole system might work. So I deleted Itunes from my computer and re-installed.
    Then I tried re-setting my ipod. So now I have nothing on my ipod.
    I also deleted everything from my library, thinking it might help to start from scratch. Nothing has worked.
    How do I "select" and "unselect" playlists so I can get up and running again?

    Here you go.
    http://discussions.apple.com/thread.jspa?messageID=607312&#607312

Maybe you are looking for

  • Aggregates Doubts

    Hello All We have a cube and aggregtaes built on that cube and daily delta load has been loaded and rollup also done, now data is available in aggrgetaes and the <b>aggregates data has been compressed</b>(No the cube data).Now we need to delete one r

  • Driver Library to communicate with SQL Server database

    Hi All, I'm new to LabView and am hoping for a few guidelines to point me in the right direction for an application that I have to develop. I have to build an API to read/write to a database (SQL Server).  Another application will essentially have th

  • Can you show me an example about %=navop%

    Hi all, On the <jbo:RowsetNavigate I found this: Tip: You can also set the action parameter at runtime by using an expression such as <%=navop%>. You would pass the action value to the RowsetNavigate tag from another portion of your page. I guess thi

  • Running Designer 6.0 against Oracle 11 - Getting error cid-20002

    When we try to Oracle Designer 6.0 against Oracle 11 we get error message cid-20002. Some of the functions work but not all and the ones that don't work gives us the error above. What is cid and where can I find info about it? suggestion pls!

  • R4870-T2D512 - installing the driver causes vista to stop booting

    Hi, I have a gigabyte ep45-ds4p motherboard with R4870-T2D512 video card and 4 GB ram and raid mirror 500GB HDD I have tried the CD driver, the driver from MSI and the driver from ATI. after installing, the PC will not boot except for safe mode. argH