Oracle
 sql >> Database >  >> RDS >> Oracle

oracolo - sequenze senza sequenza

Anche se lo sconsiglio vivamente (preferendo utilizzare una singola sequenza e accettare semplicemente che ci saranno intervalli più grandi del previsto), puoi creare la tua tabella di pseudo-sequenze

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

inserisci un paio di righe

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

e quindi scrivi una funzione per ottenere il valore della sequenza successiva

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;

Ciò bloccherà la riga nella tabella per la sequenza particolare fino a quando la transazione che ha recuperato la riga successiva non esegue il commit o esegue il rollback. Ciò ridurrà radicalmente la scalabilità della tua applicazione rispetto all'utilizzo di sequenze Oracle assicurando che solo una sessione possa inserire una riga per un particolare group_name alla volta-- gli altri si bloccheranno in attesa della sequenza. Se hai un sistema con un numero relativamente piccolo di utenti simultanei (o un numero relativamente grande di group_name valori), che potrebbe essere accettabile per te. Ma in generale è una cattiva pratica. A seconda della versione di Oracle, potresti essere in grado di utilizzare transazioni autonome per aumentare la concorrenza, ma ciò aggiunge solo un altro po' di complessità alla soluzione. Nel momento in cui sei davvero preoccupato per la scalabilità, vorresti davvero respingere l'intero progetto e utilizzare semplicemente una sequenza Oracle.