简体   繁体   中英

Unable to update column with ROWNUM in Oracle

I have a Oracle result set like below

在此处输入图片说明

I need to replace OLD_ID with RNUM. I am using the following query

   merge into x u
            using (
                      select OLD_ID, FBU_FFF_FFY,FBU_FFY_MONTH,row_number() over (partition by fbu_ffy_month, fbu_fff_ffy order by fbu_ffy_month, fbu_fff_ffy) rnum 
                      from x
            ) s
            on (u.FBU_FFF_FFY= s.FBU_FFF_FFY and u.FBU_FFY_MONTH = s.FBU_FFY_MONTH)
            when matched then update set u.OLD_ID = s.rnum;

This gives me oracle error

"unable to get a stable set of rows in the source tables"
* Cause: A stable set of rows could not be got because of large dml activity or a non-deterministic where clause.
* Action: Remove any non-deterministic where clauses and reissue the dml.

Any ideas ?

您可能在S上有重复项

don't have your tables so I could not test but how about

UPDATE (SELECT rnum, old_id
          FROM (SELECT OLD_ID,
                       FBU_FFF_FFY,
                       FBU_FFY_MONTH,
                       ROW_NUMBER ()
                       OVER (PARTITION BY fbu_ffy_month, fbu_fff_ffy
                             ORDER BY fbu_ffy_month, fbu_fff_ffy)
                          rnum
                  FROM x) s,
               x u
         WHERE     u.FBU_FFF_FFY = s.FBU_FFF_FFY
               AND u.FBU_FFY_MONTH = s.FBU_FFY_MONTH)
   SET old_id = rnum

You could try joining to itself using rowid. Something like:

SQL> create table x
(
old_id number,
val varchar2(10),
yr varchar2(4),
mth varchar2(2)
)
Table created.
SQL> insert into x values (1, 'X', '2016','01')
1 row created.
SQL> insert into x values (2, 'Y', '2016','01')
1 row created.
SQL> insert into x values (3, 'X', '2016','02')
1 row created.
SQL> insert into x values (4, 'Y', '2016','02')
1 row created.
SQL> insert into x values (5, 'X', '2016','03')
1 row created.
SQL> insert into x values (6, 'Y', '2016','03')
1 row created.
SQL> commit
Commit complete.
SQL> select * from x

    OLD_ID VAL        YR   MTH
---------- ---------- ---- ---
         1 X          2016 01 
         2 Y          2016 01 
         3 X          2016 02 
         4 Y          2016 02 
         5 X          2016 03 
         6 Y          2016 03 

6 rows selected.
SQL> -- this will update ALL rows of table x
SQL> update x
set old_id = (
    select y.rnum
    from x x2
    JOIN (
    select rowid as row_id, yr, mth, row_number() over (partition by yr, mth order by yr, mth) rnum
    from x ) y
    ON (x2.rowid = y.row_id)
    where x.rowid = x2.rowid
)
6 rows updated.
SQL> commit
Commit complete.
SQL> select * from x

    OLD_ID VAL        YR   MTH
---------- ---------- ---- ---
         1 X          2016 01 
         2 Y          2016 01 
         1 X          2016 02 
         2 Y          2016 02 
         1 X          2016 03 
         2 Y          2016 03 

6 rows selected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM