web-dev-qa-db-fra.com

Oracle: mise à jour d'une colonne de table à l'aide de ROWNUM conjointement avec la clause ORDER BY

Je veux remplir une colonne de table avec un nombre entier en cours d'exécution, je pense donc à utiliser ROWNUM. Cependant, je dois le remplir en fonction de l'ordre des autres colonnes, quelque chose comme ORDER BY column1, column2. Ce n'est malheureusement pas possible car Oracle n'accepte pas la déclaration suivante:

UPDATE table_a SET sequence_column = rownum ORDER BY column1, column2;

Ni la déclaration suivante (une tentative d'utilisation de la clause WITH):

WITH tmp AS (SELECT * FROM table_a ORDER BY column1, column2)
UPDATE tmp SET sequence_column = rownum;

Alors, comment puis-je le faire en utilisant une instruction SQL et sans recourir à la méthode d'itération du curseur en PL/SQL?

17
Lukman

Cela devrait fonctionner (fonctionne pour moi)

update table_a outer 
set sequence_column = (
    select rnum from (

           -- evaluate row_number() for all rows ordered by your columns
           -- BEFORE updating those values into table_a
           select id, row_number() over (order by column1, column2) rnum  
           from table_a) inner 

    -- join on the primary key to be sure you'll only get one value
    -- for rnum
    where inner.id = outer.id);

OU vous utilisez l'instruction MERGE. Quelque chose comme ça.

merge into table_a u
using (
  select id, row_number() over (order by column1, column2) rnum 
  from table_a
) s
on (u.id = s.id)
when matched then update set u.sequence_column = s.rnum
28
Lukas Eder
 UPDATE table_a
     SET sequence_column = (select rn 
                             from (
                                select rowid, 
                                      row_number() over (order by col1, col2)
                                from table_a
                            ) x
                            where x.rowid = table_a.rowid)

Mais cela ne sera pas très rapide et comme l'a souligné Damien, vous devez réexécuter cette instruction chaque fois que vous modifiez des données dans cette table.

3

Créez d'abord une séquence:

CREATE SEQUENCE SEQ_SLNO
  START WITH 1
  MAXVALUE 999999999999999999999999999
  MINVALUE 1
  NOCYCLE
  NOCACHE
  NOORDER;

après cela, mettez à jour la table en utilisant la séquence:

UPDATE table_name
SET colun_name = SEQ_SLNO.NEXTVAL;
2
Palavesam

Une petite correction vient d'ajouter AS RN:

UPDATE table_a
     SET sequence_column = (select rn 
                             from (
                                select rowid, 
                                      row_number() over (order by col1, col2) AS RN
                                from table_a
                            ) x
                            where x.rowid = table_a.rowid)