web-dev-qa-db-fra.com

Comment récupérer la valeur actuelle d'une séquence Oracle sans l'incrémenter?

Existe-t-il une instruction SQL permettant de récupérer la valeur d'une séquence sans l'incrémenter?.

Merci.

EDIT AND CONCLUSION

Comme le dit Justin Cave, il n’est pas utile d’essayer de "sauvegarder" le numéro de séquence

select a_seq.nextval from dual;

est assez bon pour vérifier une valeur de séquence.

Je garde toujours Ollie la bonne réponse car elle répondait à la question initiale. mais interrogez-vous sur la nécessité de ne pas modifier la séquence si vous voulez le faire.

139
frno
SELECT last_number
  FROM all_sequences
 WHERE sequence_owner = '<sequence owner>'
   AND sequence_name = '<sequence_name>';

Vous pouvez obtenir diverses métadonnées de séquence à partir de user_sequences, all_sequences et dba_sequences.

Ces vues fonctionnent d'une session à l'autre.

EDIT:

Si la séquence est dans votre schéma par défaut, alors:

SELECT last_number
  FROM user_sequences
 WHERE sequence_name = '<sequence_name>';

Si vous voulez toutes les métadonnées, alors:

SELECT *
  FROM user_sequences
 WHERE sequence_name = '<sequence_name>';

J'espère que ça aide...

EDIT2:

Une façon longue de le faire de manière plus fiable si la taille de votre cache n’est pas 1 serait:

SELECT increment_by I
  FROM user_sequences
 WHERE sequence_name = 'SEQ';

      I
-------
      1

SELECT seq.nextval S
  FROM dual;

      S
-------
   1234

-- Set the sequence to decrement by 
-- the same as its original increment
ALTER SEQUENCE seq 
INCREMENT BY -1;

Sequence altered.

SELECT seq.nextval S
  FROM dual;

      S
-------
   1233

-- Reset the sequence to its original increment
ALTER SEQUENCE seq 
INCREMENT BY 1;

Sequence altered.

Sachez simplement que si d’autres utilisent la séquence pendant ce temps, ils (ou vous-même) pourriez avoir

ORA-08004: sequence SEQ.NEXTVAL goes below the sequences MINVALUE and cannot be instantiated

Vous pouvez également définir le cache sur NOCACHE avant la réinitialisation, puis sur sa valeur d'origine pour vous assurer que vous n'avez pas mis en cache beaucoup de valeurs.

156
Ollie

select MY_SEQ_NAME.currval from DUAL;

N'oubliez pas que cela ne fonctionne que si vous avez exécuté select MY_SEQ_NAME.nextval from DUAL; dans les sessions en cours.

115
RonK

Ma réponse originale était factuellement incorrecte et je suis heureux qu'elle ait été supprimée. Le code ci-dessous fonctionne dans les conditions suivantes a) vous savez que personne d'autre n'a modifié la séquence b) la séquence a été modifiée par votre session. Dans mon cas, j’ai rencontré un problème similaire dans lequel j’appelais une procédure qui modifiait une valeur et je suis convaincu que l’hypothèse est vraie.

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

Malheureusement, si vous n'avez pas modifié la séquence de votre session, je pense que d'autres ont raison de dire que NEXTVAL est la seule solution.

0
georgejo

En réalité, ce n’est pas une réponse et j’y aurais inscrit un commentaire si la question n’avait pas été verrouillée. Cela répond à la question:

Pourquoi le voudrais-tu?

Supposons que vous avez une table avec la séquence en tant que clé primaire et que la séquence est générée par un déclencheur d'insertion. Si vous souhaitez que la séquence soit disponible pour les mises à jour ultérieures de l'enregistrement, vous devez disposer d'un moyen d'extraire cette valeur.

Afin de vous assurer que vous obtenez le bon, vous pouvez vouloir encapsuler la requête INSERT et la requête de RonK dans une transaction.

Requête de RonK:

select MY_SEQ_NAME.currval from DUAL;

Dans le scénario ci-dessus, la mise en garde de RonK ne s'applique pas car l'insertion et la mise à jour auraient lieu dans la même session.

0
Ainsworth

J'ai également essayé d'utiliser CURRVAL, dans mon cas pour savoir si un processus insérait de nouvelles lignes dans une table avec cette séquence comme clé primaire. Mon hypothèse était que CURRVAL serait la méthode la plus rapide. Mais a) CurrVal ne fonctionne pas, il obtiendra simplement l'ancienne valeur car vous êtes dans une autre session Oracle, jusqu'à ce que vous fassiez un NEXTVAL dans votre propre session. Et b) une select max(PK) from TheTable est également très rapide, probablement parce qu'une PK est toujours indexée. Ou select count(*) from TheTable. J'expérimente toujours, mais les deux sélections semblent rapides.

Une séquence ne me dérange pas, mais dans mon cas, je pensais beaucoup voter, et je détesterais l’idée de très grandes lacunes. Surtout si un simple SELECT serait aussi rapide.

Conclusion:

  • CURRVAL est plutôt inutile, car il ne détecte pas NEXTVAL à partir d’une autre session, il ne renvoie que ce que vous saviez déjà de votre précédent NEXTVAL.
  • SELECT MAX (...) FROM ... est une bonne solution, simple et rapide, en supposant que votre séquence soit liée à cette table.
0
Roland