IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Oracle Discussion :

commit régulier avec un delete en masse


Sujet :

Oracle

  1. #1
    Rédactrice

    Avatar de kalyparker
    Femme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Janvier 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 327
    Points : 2 998
    Points
    2 998
    Par défaut commit régulier avec un delete en masse
    Bonjour à tous,

    Voilà j'ai un gros pb avec oracle 9i

    Je voudrais faire un delete complet d'une table très volumineuse et commiter tous les 5000 enregistrements.

    Avez vous une idée de comment je pourrais faire ?

    Merci

  2. #2
    Membre confirmé Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Points : 481
    Points
    481
    Par défaut
    Salut,
    Sol 1 : un bon vieux truncate
    Sol 2 : Une boucle PL

    A+

  3. #3
    Rédactrice

    Avatar de kalyparker
    Femme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Janvier 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 327
    Points : 2 998
    Points
    2 998
    Par défaut
    Oaip le bon vieux truncate serais effectivement bienvenue,

    mais le pb c'est que je dois obligatoirement avoir des logs de petites tailles car j'ai 2 bdd couplé avec dataguard et que lorsque je fait un truncate il perd les pédale et lorsque je fais un

    dataguard se plante car il ne peux pas traité autant d'info d'un coup.

    Je voulais faire une procédure PL, mais je ne sais pas par où commencer ?!

  4. #4
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    CURSOR et BULK COLLECT

  5. #5
    Rédactrice

    Avatar de kalyparker
    Femme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Janvier 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 327
    Points : 2 998
    Points
    2 998
    Par défaut
    Merci de ta réponse Fred_D

    Ma question va surement te paraître idiote mais c'est quoi un bulk collect ?

    J'ai essayer de faire ça, mais ce n'est pas très convainquant...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    declare
      cpt number := 0; 
      max number;
     
    begin
    	 select count(*) into max from ma_table;
       WHILE cpt < max
       LOOP
            delete  ma_table where ROWNUM < 5000 ;
             cpt := cpt + 5000;
             commit;
        end loop;
        commit;
    end;
    /
    Si tu penses qu'un bulk collect est necessaire pourrais tu m'en dire plus ?

  6. #6
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    utilise la recherche pour trouver des exemples ou lis ce document : http://sheikyerbouti.developpez.com/...=Chap1#L1.2.20

  7. #7
    Rédactrice

    Avatar de kalyparker
    Femme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Janvier 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 327
    Points : 2 998
    Points
    2 998
    Par défaut
    Je ne vois pas bien en quoi le bulk collect peux m'aider...
    J'ai tester celà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    Declare
       TYPE TYP_TAB_EMP IS TABLE OF ma_table%Rowtype ;
        Tabemp TYP_TAB_EMP ;
      Begin  
       Select
            *
          BULK COLLECT
          Into
             Tabemp
         From 
           ma_table;
         For i IN Tabemp.first..Tabemp.last Loop
           delete from ma_table where cle1=Tabemp(i).cle1 and cle2=Tabemp(i).cle2;
    	   commit;
         End loop;
       End ;
       /
    Dans ce code je fait un commit tout les enregistrements et Oracle me jette par manque de mémoire...
    En plus la clé primaire de ma table est composé ce qui m'oblige à faire la jointure sur 2 champs.

    Je suis perdue...

    J'ai vu sur internet qu'il existerais quelque chose comme
    ma_table.DELETE(val1, val2);
    qui permet de supprimer les enregistrements de la ligne val1 à la ligne val2.

    En savez vous plus ?

  8. #8
    Membre éprouvé Avatar de Yorglaa
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    845
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2004
    Messages : 845
    Points : 931
    Points
    931
    Par défaut
    regarde à nouveau la doc que t'a donné Fred_D !

    la boucle où tu fais le delete ne doit pas être un FOR... mais FORALL (sans End Loop)

  9. #9
    Rédactrice

    Avatar de kalyparker
    Femme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Janvier 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 327
    Points : 2 998
    Points
    2 998
    Par défaut
    Alors voila je crois que je me suis bien battu et que j'ai finalement gagné !
    J'ai laissé tomber le bulk collect pour quelque chose de plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    declare
      v_pas number; 
      v_count number;
    begin
    LOOP
       v_pas := 5000;
     
       delete from ma_table where rownum < v_pas;   
       commit; 
       select count(*) into v_count from ma_table;
     
    if v_count = 0 then
       exit;
    end if;
     
    END LOOP;
    end;
    Ce n'est peut être pas la meilleure solution, mais au moins elle marche !
    Merci à vous de votre aide.

  10. #10
    Membre averti Avatar de Wurlitzer
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 469
    Points : 408
    Points
    408
    Par défaut
    Le bulk collect pourrait t'aider si tu avais besoin de faire un select pour trouver les enregistrements à supprimer. Dans ton cas la condition est directement dans le delete. C'est donc plus simple.

    Ta solution est correcte. Je te propose l'optimisation suivante qui évite de faire un count et donc potentiellement un FULL SCAN a chaque itération de boucle. Ce qui peut change beaucoup de chose du point de vue des perfs


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    declare
      v_pas number; 
      p_nb_delete number;
    begin
    LOOP
       v_pas := 5000;
     
       DELETE FROM ma_table WHERE rownum <= v_pas;   
       p_nb_delete := SQL%ROWCOUNT;   
       commit; 
        
    IF p_nb_delete < v_pas then
       exit;
    end IF;
     
    END LOOP;
    end;

  11. #11
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    et pourquoi pas un WHILE ROWCOUNT>0 ?

  12. #12
    Rédactrice

    Avatar de kalyparker
    Femme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Janvier 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 327
    Points : 2 998
    Points
    2 998
    Par défaut
    Merci pour ces précieux conseils.
    Effectivement Wurlitzer, ta solution est beaucoup moins gourmandes que la mienne.
    Quand à ton optimisation Fred_D, juste par curiosité qu'est ce que cela m'apporte ? La structure loop exit est-elle plus gourmande que while loop ?

  13. #13
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    c'est juste moins compliqué

  14. #14
    Membre averti Avatar de Wurlitzer
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 469
    Points : 408
    Points
    408
    Par défaut
    Je vois deux raisons pour ne pas utiliser le WHILE ROWCOUNT>0 :

    • La première (assez mauvaise ), j'y avais pas pensé.....
    • La seconde, est que plus loin dans mon code j'additionne les p_nb_delete pour afficher le nombre de lignes totales supprimées


    Sinon, je suis d'accord que c'est plus élégant

  15. #15
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    pour la seconde SQLROWCOUNT + ((nb_boucle - 1) * v_pas)

  16. #16
    Membre averti Avatar de Wurlitzer
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 469
    Points : 408
    Points
    408
    Par défaut
    La nuit portant conseil et juste pour le plaisir de chipoter un peu

    • Si on doit compter le nombre de boucles on peut compter les lignes directement
    • Avec WHILE ROWCOUNT>0 tu es moins optimisé que car tu fais presque toujours un DELETE de trop (puisque que le dernier DELETE est presque toujours un nombre de ligne inferieur a w_pas mais > 0). Il faudrait ecrire WHILE ROWCOUNT = v_pas pour eviter ca

  17. #17
    Rédactrice

    Avatar de kalyparker
    Femme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Janvier 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 327
    Points : 2 998
    Points
    2 998
    Par défaut
    Pour l'optimisation, vous êtes efficaces dans votre genre !

    Wurlitzer, ta dernière solution me laisse perplexe.
    Parce que si je fait un while rowcount=v_pas alors justement je ne passe pas dans la boucle pour le dernier delete et donc lorsque je sort de ma boucle il me reste encore des enregistrements dans ma table, non ?

    Je vais rester sur la solution de Fred_D.

  18. #18
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    si c'est bon, l'avant dernière boucle fera un rowcount = v_pas, du coup tu passes le WHILE pour faire ce qui sera la dernière boucle

    Bravo Wurlitzer

  19. #19
    Rédactrice

    Avatar de kalyparker
    Femme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Janvier 2007
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 327
    Points : 2 998
    Points
    2 998
    Par défaut
    Oh la la, honte sur moi

    effectivement, vous avez raison, je n'avais pas bien saisi le but de la manoeuvre et pis c'etait le matin alors...
    Non, je sais que je n'ai pas d'excuse alors je m'arrete...

    A nouveau merci à vous et

    ++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Insertion en masse et commit régulier
    Par esteban dans le forum SGBD
    Réponses: 1
    Dernier message: 02/07/2008, 19h01
  2. Configuration commit automatique avec add et delete Subversion
    Par R1D3M4N dans le forum Administration système
    Réponses: 1
    Dernier message: 23/06/2008, 00h16
  3. Réponses: 4
    Dernier message: 09/12/2005, 17h40
  4. Delete de masse
    Par genio dans le forum Oracle
    Réponses: 5
    Dernier message: 09/12/2005, 16h30
  5. Pb avec ON DELETE/UPDATE CASCADE
    Par trotters213 dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 09/03/2005, 11h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo