sql - UPDATE statement: re-evaluate subquery after each SET -
create table test (id number(3)); insert test values (1); insert test values (2); insert test values (2); insert test values (3); insert test values (4); insert test values (4); insert test values (5);
i want make numbers in test
unique (like {1,2,3,4,5,6,7}
- i.e. remove doubles) using query:
update test u set u.id = (select max(nn.id) test nn) + 1 1 < ( select tt.rown (select rowid, row_number() on ( partition t.id order t.id) rown test t) tt tt.rowid = u.rowid );
the above query updates table {1,2,3,4,5,6,6}
. replaces second 2
6
correctly, second 4
becomes 6
also, should 7
. existing non-duplicates should not replaced, second-onward duplicates.
the problem above update statement (select max(nn.id) test nn)
evaluated once , cached, depends on updated. possible force re-evaluation of (select max(nn.id) test nn)
after each set? tried hints /*+nocache*/
without success.
in other words, during update, need take account fields have been updated.
anyone ideas?
i assume solved non-deterministic function, don't want make functions. edit: if try compute id function ora-04091: table test mutating, trigger/function may not see it. using pragma autonomous_transaction;
gives same result above query.
solution precalculated ids, bypassing query re_evaluation
audriym solved (cf. comments) ms sql server 2008 using ctes. there no alternative in oracle ctes far know, because audriym's solution based on precalculated values ids, though translate in oracle subqueries. , here is:
update test u set u.id = ( select newids.newid ( select ranked.rowid, ranked.m + row_number() on (order ranked.id, ranked.r) newid ( select t.rowid, t.id, row_number() on ( partition t.id order t.id) r, max(id) over() m test t ) ranked ranked.r > 1 ) newids u.rowid = newids.rowid ) u.rowid in ( select ranked.rowid ( select t.rowid, t.id, row_number() on ( partition t.id order t.id) r, max(id) over() m test t ) ranked ranked.r > 1 );
solution without precalculated ids, using query re_evaluation
still not found , question remains unanswered.
try use following statement. table doesn't allow identify row example id=2 link table row_number can use rowid
update test set id = (select rn (select row_number() on (order id) rn test ) t1 t1.rowid=test.rowid )
Comments
Post a Comment