7
votes

Besoin de réinitialiser la valeur de la séquence dans Oracle

Je travaille avec le printemps et l'hibernation pour développer des applications Web à Java. Supposons que j'ai une table. Lorsque je supprimai certains enregistrements de cette table, je dois parfois réinitialiser la valeur du champ de clé primaire.

Disons que j'ai 10 enregistrements dans une table et je supprime les 5 derniers enregistrements. Maintenant, lorsque j'insère de nouveaux enregistrements, la valeur du champ de la clé principale doit être démarrée à 6 code> mais il démarrerait à 11 code>. P>

si je Besoin de démarrer la valeur de la clé principale à 6 code> ( maximum +1 code>) dans MySQL, j'ai juste besoin d'exécuter l'instruction SQL suivante. P>

alter table table_name auto_increment=1;


2 commentaires

Pourquoi avez-vous besoin de la séquence pour être dense? Comment l'utilisez-vous ? Peut-être que vous pouvez faire avec un rang () (ou dense_rank () ) dans votre requête


Pourquoi pensez-vous que vous devez réutiliser des valeurs PK des rangées supprimées? Les chiffres sont totalement dénués de sens. Alors continuez avec 11 et ne vous souciez pas.


4 Réponses :


6
votes

En référence à Oracle's Séquence Alter Documentation,

  • Pour redémarrer la séquence à un numéro différent, vous devez tomber et Recréez-le.

    Vous devez passer la valeur maximale actuelle de la colonne clé principale pour générer le numéro de séquence suivant.
    Si vous continuez à supprimer des derniers enregistrements et souhaitez réutiliser les valeurs de séquence déjà générées, vous pouvez avoir besoin de redémarrer cette séquence encore et encore. La chute d'une séquence peut conduire à SQLException si le serveur reçoit une demande de valeur suivante avant que la séquence soit prête à servir.

    Vous pouvez également trouver des notes utiles sur les séquences Oracle ici .


2 commentaires

Techniquement, vous pouvez modifier la séquence pour incrémenter négativement, en choisir, puis rétablir l'incrément de manière positive.


@Adammusch Oui, c'est possible et l'objet de séquence existant n'est pas perdu.



17
votes

Les raisons pour lesquelles vous ne devriez pas réinitialiser la valeur si elle est utilisée:

Que se passe-t-il si vous avez 20 enregistrements et supprimez des enregistrements 5-10? Vous avez un écart au milieu qui redéfinir la séquence ne résoudra pas. Les séquences seront Jamais em> Générer une séquence libre d'écart de nombres , un 1, 2 .. n em>. p>

si vous appelez .nextval code> et n'utilisez pas la valeur, c'est parti em>. Allez-vous laisser tomber et recréer la séquence? Si vous démarrez un insert et annulez-le et Oracle Rolls Retour Ce que vous avez fait ces valeurs sont parti em>. Si vous définissez nocache code>, vous aurez moins de lacunes mais à un coût d'une touche de performance; Est-ce que ça vaut le coup? P>

Votre cache doit être réglé sur le nombre d'insertions que vous attendez à faire à tout moment à travers toutes les sessions em> pour éviter tout problème de performance. Les séquences sont conçues pour fournir une manière très rapide et évolutive de créer une clé de substitution sans aucun verrouillage, etc. pas em> pour générer l'ensemble des entiers positifs. P>

à la fin de la jour, cela ne devrait pas avoir d'importance dans le moindre. Si vous comptez sur une séquence ininterrompue comme clé de votre table, vous avez un problème avec vos données plutôt que des séquences. P>


Répondre à la question: h3>

pour réellement Répondez à votre question que vous auriez besoin de: p>

  1. Tout d'abord, découvrez quelle valeur ID (séquence) maximale dans votre table est. LI>
  2. Alors Doublez et recréez la séquence . li> ol>

    Trouver la valeur maximale signifie que vous auriez besoin de recréer la séquence de manière dynamique au coût d'un autre coup sur la performance. p>

    Si vous essayez d'insérer quelque chose dans votre table tandis que cela se produit échouera et peut invalider tout déclenchement ou d'autres objets utilisant la séquence: P>

    SQL>
    SQL> declare
      2
      3     l_max_id number;
      4     l_max_seq number;
      5
      6  begin
      7
      8     -- Get the maximum ID
      9     select max(id) into l_max_id
     10       from tmp_test;
     11
     12     -- Get the current sequence value;
     13     select test_seq.currval into l_max_seq
     14       from dual;
     15
     16     -- Alter the sequence to increment by the difference ( -5 in this case )
    .
     17     execute immediate 'alter sequence test_seq
     18                          increment by ' || ( l_max_id - l_max_seq );
     19
     20     -- 'increment' by -5
     21     select test_seq.nextval into l_max_seq
     22       from dual;
     23
     24     -- Change the sequence back to normal
     25     execute immediate 'alter sequence test_seq
     26                          increment by 1';
     27
     28  end;
     29  /
    
    PL/SQL procedure successfully completed.
    
    SQL>
    SQL> select test_seq.currval from dual;
    
       CURRVAL
    ----------
            15
    
    SQL>
    


4 commentaires

Non, vous n'avez pas besoin de déposer et de recréer une séquence pour le réinitialiser. Vous pouvez utiliser une combinaison de deux déclarations alter et une requête.


Je ne savais pas, merci @jeffrey, je n'ai jamais eu besoin de faire quoi que ce soit comme ça. C'est toujours 2 déclarations cependant de l'avantage, je suppose que l'objet reste.


Oui - y compris les subventions et les options de séquence telles que les paramètres de cache


Concernant la réponse de Jeffrey Kemp, soyez conscient de l'utilisation de .curval - Vous avez besoin d'un appel à .nSnextval avant qu'il ne puisse travailler . Je devais utiliser Sélectionnez Last_Number à partir d'utilisateurs user_numences où sequence_name = 'SEQ_MY_TABLE'; à la place.



9
votes

Ce qui suit fonctionne également (augmente votre valeur de séquence de 100):

select my_sequence.nextval from dual connect by level <= 100;


2 commentaires

Cela n'a pas fonctionné pour moi, au moins avec Oracle version 11g. J'ai passé un test où j'ai exécuté ces déclarations: Pastebin.com/th1mkw8b . "NextVal" n'a augmenté que par 51 après "Connecter par niveau <= 1000".


Merci beaucoup pour ça! Lucky d'avoir trébuché dessus après avoir gaspillé environ 3 heures de ma vie.



0
votes

Ce truc fonctionne pour moi. Dans ma séquence (usersutpl_userutpl_sq), le dernier numéro était 53. Le dernier identifiant de ma table était 83 xxx

puis 83 - 53 = 31. Donc: xxx

et sa modifie le dernier numéro. : D


0 commentaires