How can I use "FOR UPDATE" with a JOIN on Oracle?

6.8k views Asked by At

The answer to another SO question was to use this SQL query:

SELECT o.Id, o.attrib1, o.attrib2 
  FROM table1 o
  JOIN (SELECT DISTINCT Id 
          FROM table1, table2, table3 
         WHERE ...) T1 ON o.id = T1.Id

Now I wonder how I can use this statement together with the keyword FOR UPDATE. If I simply append it to the query, Oracle will tell me:

ORA-02014: cannot select FOR UPDATE from view

Do I have to modify the query or is there a trick to do this with Oracle? With MySql the statement works fine.

2

There are 2 answers

4
davek On BEST ANSWER

try:

select ..... 
from <choose your table>
where id in (<your join query here>) for UPDATE;

EDIT: that might seem a bit counter-intuitive bearing in mind the question you linked to (which asked how to dispense with an IN), but may still provide benefit if your join returns a restricted set. However, there is no workaround: the oracle exception is pretty self-explanatory; oracle doesn't know which rows to lock becasue of the DISTINCT. You could either leave out the DISTINCT or define everything in a view and then update that, if you wanted to, without the explicit lock: http://www.dba-oracle.com/t_ora_02014_cannot_select_for_update.htm

2
Alex Poole On

It may depend what you want to update. You can do ... FOR UPDATE OF o.attrib1 to tell it you're only interested in updating data from the main table, which seems likely to be the case; this means it will only try to lock that table and not worry about the implicit view in the join. (And you can still update multiple columns within that table, naming one still locks the whole row - though it will be clearer if you specify all the columns you want to update in the FOR UPDATE OF clause).

Don't know if that will work with MySQL though, which brings us back to Mark Byers point.