Oracle
 sql >> Base de données >  >> RDS >> Oracle

oracle - séquences sans séquence

Bien que je le déconseille fortement (en préférant utiliser une seule séquence et en acceptant simplement qu'il y aura des écarts plus importants que prévu), vous pouvez créer votre propre table de pseudo-séquence

CREATE TABLE my_sequences (
  sequence_name VARCHAR2(30) PRIMARY KEY,
  sequence_val  NUMBER
);

insérer quelques lignes

INSERT INTO my_sequences( sequence_name, sequence_val )
  VALUES( 'GroupA', 1 );
INSERT INTO my_sequences( sequence_name, sequence_val )
  VALUES( 'GroupB', 1 );

puis écrivez une fonction pour obtenir la valeur de séquence suivante

CREATE FUNCTION get_nextval( p_sequence_name IN VARCHAR2 )
  RETURN NUMBER
IS
  l_val NUMBER;
BEGIN
  SELECT sequence_val
    INTO l_val
    FROM my_sequences
   WHERE sequence_name = p_sequence_name
     FOR UPDATE;

  UPDATE my_sequences
     SET sequence_val = sequence_val + 1
   WHERE sequence_name = p_sequence_name;

  RETURN l_val;
END;

Cela verrouillera la ligne dans la table pour la séquence particulière jusqu'à ce que la transaction qui a récupéré la ligne suivante soit validée ou annulée. Cela réduira radicalement l'évolutivité de votre application par rapport à l'utilisation de séquences Oracle en garantissant qu'une seule session peut insérer une ligne pour un group_name particulier à la fois - les autres bloqueront l'attente de la séquence. Si vous avez un système avec un nombre relativement faible d'utilisateurs simultanés (ou un nombre relativement important de group_name valeurs), cela peut être acceptable pour vous. Mais en général c'est une mauvaise pratique. Selon la version d'Oracle, vous pourrez peut-être utiliser des transactions autonomes pour augmenter la simultanéité, mais cela ne fait qu'ajouter un peu plus de complexité à la solution. Au moment où vous êtes vraiment préoccupé par l'évolutivité, vous voudriez vraiment repousser l'ensemble de la conception et utiliser simplement une séquence Oracle.