I am trying to update multiple columns in Oracle and after going through a few scenarios settled on the code below.
My problem is that the more streamlined code is not updating what i need while the more complicated one does - i am trying to attain this via minimal processing power as i'm looking at hundreds of thousands of updates or even more.
So the first code:
UPDATE table@database1 i2
SET (i2.access, i2.permission) =
(select
i2m.access, i2m.permission
from temporarytable ss
JOIN table2 pgm
ON ss.secgroup = pgm.string
JOIN table i2m
ON pgm.hmy = i2m.hgroup
AND ss.pername = i2m.sobjname
JOIN table2@database1 pg
ON ss.secgroup = pg.string
WHERE
pg.string = 'string' -- this limits the updates to a specific subset of data
and i2m.hmy > 0 -- this for some freak records in both tables that are missing a primary key
and pg.hmy = i2.hgroup -- this matches the key of the 'string' from above to the records i need to update
and ss.pername = i2.sobjname -- further condition on which records to update. so only the ones that match from the temp table to the target table
and ss.orig_hmy = i2.hmy) -- further condition to make sure i am updating only records matching between temp table and target table
Now, if I run this, instead of updating only about 700 records that match the above subquery it updates all records from table 'table@database1' and I can't see why (probably one of those things that I don't get about Oracle :) )
But if I run the below - which the only difference is that I insert the whole subquery in a 'where exists' - then this does update only what I need. My issue is that the way I understand it, the subquery is run twice - once in the update and once in the where clause - which I would say is a waste of processing power.
UPDATE table@database1 i2
SET (i2.access, i2.permission) =
(select
i2m.access, i2m.permission
from temporarytable ss
JOIN table2 pgm
ON ss.secgroup = pgm.string
JOIN table i2m
ON pgm.hmy = i2m.hgroup
AND ss.pername = i2m.sobjname
JOIN table2@database1 pg
ON ss.secgroup = pg.string
WHERE
pg.string = 'string'
and i2m.hmy > 0
and pg.hmy = i2.hgroup
and ss.pername = i2.sobjname
and ss.orig_hmy = i2.hmy)
where exists (select
i2m.access, i2m.permission
from temporarytable ss
JOIN table2 pgm
ON ss.secgroup = pgm.string
JOIN table i2m
ON pgm.hmy = i2m.hgroup
AND ss.pername = i2m.sobjname
JOIN table2@database1 pg
ON ss.secgroup = pg.string
WHERE
pg.string = 'string'
and i2m.hmy > 0
and pg.hmy = i2.hgroup
and ss.pername = i2.sobjname
and ss.orig_hmy = i2.hmy)
note: In case it doesn't show, I have multiple DBs with the same schema. I am trying to update a table across DBs with the information from a master schema. The Temp table acts as a repository for the records that are different and need updating - no reason in updating millions of records if only 15% differ from the master schema.
mergeif you don't like this method of updating tables.whereclause on theupdatestatement. Nothing Oracle specific about that, in all platforms I'm familiar that with update without where updates every row.