Oracle – Sequenze

Sequenze Oracle Encyclopedia

Oracle

Oracle

Funzionamento

Architettura

File

Processi

La Memoria

Dizionario di dati

Sequenze

Interrogazioni gerarchiche

Questo articolo è basato sulla versione 8.1.6 di Oracle.

Una sequenza è un oggetto del database Oracle, proprio come una tabella, una vista, ecc. In altre parole, appartiene a un utente, possiamo manipolarlo, modificarlo, a condizione di avere i diritti necessari. Questo articolo mira a definire cos’è una sequenza e a presentare le possibilità che questo oggetto offre.

Definizione di una sequenza

Definire una sequenza è equivalente a definire una sequenza di interi. L’evoluzione di questa sequenza è governata da un certo numero di parametri, che vedremo insieme un po’ più tardi. Questo può essere usato per:

  • generare chiavi uniche nelle tabelle
  • avere un contatore di informazioni, che incrementiamo quando vogliamo
  • ecc…

La mia prima sequenza

Siccome la maggior parte dei parametri ha un valore predefinito, non è necessario specificarli tutti quando vogliamo creare una nuova sequenza. Quindi ecco l’ordine minimo SQL per creare una sequenza:

CREATE SEQUENCE ma_sequence;

In questo ordine, “my_sequence” è ovviamente il nome della sequenza che volete creare; una sequenza ha un nome, proprio come una tabella, o qualsiasi altro oggetto in Oracle. Questo ti permette di manipolarlo… Se esegui questo comando SQL e se hai i privilegi necessari (cioè CREATE SEQUENCE), Oracle ti risponderà gentilmente “Sequenza creata”. Ma come si fa a vedere cosa c’è in quella sequenza? Come sfruttarlo?

L’interrogazione di una sequenza è fatta usando le “pseudo-colonne” CURRVAL e NEXTVAL. È chiamata una pseudo-colonna perché è gestita un po’ come una colonna di tabella, ma non è una colonna di tabella.

  • La pseudo-colonna CURRVAL restituisce il valore corrente della sequenza.
  • La pseudo-colonna NEXTVAL incrementa la sequenza e restituisce il nuovo valore.

Esempi:

===SQL> select ztblseq.currval from dual;select ztblseq.currval from dual*ERREUR à la ligne 1 :ORA-08002: séquence ZTBLSEQ.CURRVAL pas encore définie dans cette session===

Questo errore è dovuto al fatto che non abbiamo ancora inizializzato la nostra sequenza, e stiamo cercando di recuperare il suo valore attuale.

Quando si usa una sequenza per la prima volta, si dovrebbe usare NEXTVAL per inizializzarla.

===SQL> select ztblseq.nextval from dual; NEXTVAL---------1===

CURRVAL ora restituisce 1. Se è così, prova…

===SQL> select ztblseq.currval from dual; CURRVAL---------1===

Ora che sappiamo come recuperare il valore di una sequenza, e sappiamo come incrementarla, vediamo quali sono i diversi parametri che ci permettono di definire una sequenza:

Identificatore di sequenza

In uno stesso database, diversi oggetti possono avere lo stesso nome, a condizione che siano ognuno in uno schema diverso. Inoltre, è possibile specificare in quale schema si desidera creare la sequenza:

CREATE SEQUENCE schema_toto.sequence_de_toto;

Valore iniziale e incremento

Di default, una sequenza inizia con il valore 1, e incrementa da 1 a 1 ad ogni chiamata a NEXTVAL. Ma si possono tranquillamente specificare i propri parametri:

CREATE SEQUENCE ma_sequence START WITH 5 INCREMENT BY 3;

In questo esempio, abbiamo definito la sequenza 5, 8, 11, 14, 17, 20…
I parametri START WITH e INCREMENT BY possono essere usati indipendentemente.
Per fare una sequenza decrescente, basta specificare un valore negativo al parametro INCREMENT BY:

CREATE SEQUENCE ma_sequence INCREMENT BY -10;

Valore massimo e valore minimo

Implicitamente (per default), Oracle ha creato la nostra prima sequenza con i seguenti parametri (tra gli altri):

CREATE SEQUENCE ma_sequence NOMAXVALUE NOMINVALUE;

Se lo si desidera, si può impostare un tetto (per una sequenza ascendente) o un pavimento (per una sequenza discendente):

CREATE SEQUENCE ma_sequence START WITH 1 INCREMENT BY 1 MAXVALUE 9999;CREATE SEQUENCE ma_sequence START WITH -1 INCREMENT BY -1 MINVALUE -9999;

Looping della sequenza

Quando la sequenza raggiunge il suo valore massimo (risp. mini), gli si può chiedere di fermarsi (Oracle restituirà un errore al prossimo tentativo di usare NEXTVAL), o di riprendere al suo valore mini (o massimo) e riprendere il conteggio.
Questa sequenza conterà fino a 10 e poi restituirà un errore al prossimo NEXTVAL:

CREATE SEQUENCE ma_sequence START WITH 1 MINVALUE -10 MAXVALUE 10 NOCYCLE;

Questa sequenza conterà da 1 a 10, poi da -10 a 10, poi da -10 a 10… :

CREATE SEQUENCE ma_sequence START WITH 1 MINVALUE -10 MAXVALUE 10 CYCLE;

Per default, una sequenza non va in loopback (caso #1)

Caching values

Per ottimizzare l’uso delle sequenze, Oracle può essere istruito a mettere in cache un certo numero di valori della sequenza:

CREATE SEQUENCE ma_sequence CACHE 100;

Per default, Oracle mantiene 20 valori in cache.

Il caching è importante?
Sì, può avere un effetto significativo sulle prestazioni. Si può mettere un alto numero di valori nella cache.

Ordine di creazione forzata

Questa impostazione ha effetto solo sui server che funzionano in modalità parallela. Per verificarlo, esegui il seguente comando SQL:

SELECT name, value FROM v$parameter WHERE name = 'parallel_server';

Se stai eseguendo in modalità parallela (TRUE), quando più NEXTVAL sono eseguiti simultaneamente, non sono sempre processati nell’ordine corretto. Inoltre, è necessario abilitare l’opzione ORDER come segue:

CREATE SEQUENCE ma_sequence ORDER;

Modificare una sequenza

Negli esempi precedenti, abbiamo visto come creare una sequenza specificando gli attributi che definiscono il suo comportamento. Questi attributi possono essere modificati dopo la creazione della sequenza. Tutto quello che dovete fare è usare il comando SQL ALTER SEQUENCE.Ecco un esempio di concatenamento dei comandi SQL:

===SQL> create sequence ma_sequence start with 1 minvalue 0;Séquence créée.SQL> select ma_sequence.nextval from dual; NEXTVAL---------1SQL> select 'La valeur courante est ' || ma_sequence.currval from dual;'LAVALEURCOURANTEEST'||MA_SEQUENCE.CURRVAL---------------------------------------------------------------La valeur courante est 1SQL> alter sequence ma_sequence increment by 20;Séquence modifiée.SQL> select ma_sequence.nextval from dual; NEXTVAL--------- 21SQL> select ma_sequence.nextval + ma_sequence.nextval from dual;MA_SEQUENCE.NEXTVAL+MA_SEQUENCE.NEXTVAL--------------------------------------- 82SQL> alter sequence ma_sequence increment by -41 maxvalue 100 cycle nocache;Séquence modifiée.SQL> select ma_sequence.nextval from dual; NEXTVAL---------0SQL> select ma_sequence.nextval from dual; NEXTVAL--------- 100SQL> select ma_sequence.nextval from dual; NEXTVAL--------- 59===

Avete notato che quando si esegue “select my_sequence.nextval + my_sequence.nextval from dual;”, viene usato solo uno stesso valore di sequenza? Oracle considera NEXTVAL come una pseudo-colonna, e quindi in questo comando SQL, la “preleva” solo una volta a livello di database, la seconda volta preleva il valore caricato in memoria.

Modificare una sequenza

Una domanda che sorge spesso sui forum Oracle è “Come faccio a creare una colonna di tabella auto-incrementante, allo scopo di renderla una chiave primaria? Infatti, Oracle non ha l’opzione auto_increment che si trova in alcuni DBMS (incluso MySQL).

Il principio è il seguente:

  • creare una sequenza che genererà valori interi unici
  • creare un TRIGGER che si attiverà ad ogni INSERT, per alimentare il campo desiderato con un valore unico.

Ecco un esempio di trigger:

===create trigger t_matable_pkbefore insert on matable for each rowbegin select seq_matable_pk.nextval into :new.x from dual;end;===

… dove “x” è il nome del campo da incrementare automaticamente.

Questo esempio non gestisce il controllo di unicità del valore che stiamo per inserire, ma se il campo viene alimentato SOLO utilizzando la sequenza ad esso dedicata, e se questa sequenza non è impostata per andare in loopback, non c’è motivo che si verifichi un errore di chiave duplicata…

Una sequenza senza buchi?

Poiché una sequenza può essere interrogata in qualsiasi momento da qualsiasi utente Oracle con diritti sufficienti, SEQUENCES NON DEVE essere considerata come un modo per generare una sequenza di numeri senza “buchi”. Esempio: nel caso di un feed a chiave primaria, se un record è stato inserito e poi la transazione è stata fatta retrocedere, allora la sequenza non retrocede, e la prossima volta che viene inserita, sembrerà che la sequenza abbia saltato uno o più numeri.Quindi: una sequenza fornisce un modo per ottenere valori unici, ma non necessariamente continui.

Bibliografia

  • Documentazione Oracle: http://www.oradoc.com
  • Schema della sintassi CREATE SEQUENCE: http://www.oradoc.com/ora816/server.816/a76989/ch4g23.gif

Articolo scritto da Tittom

Tricks & suggerimenti rilevanti trovati nella base di conoscenza

22/09 6:56 PM Connessione a un database Oracle in php (Oracle)
Oracle Altri suggerimenti su “Oracle”

Discussioni rilevanti trovate nel forum

20/06 5:48 PM importare database oracle Importare database oracle Sviluppo 17/02 9:48 AM->abdou 9
31/05 16:27 sql oracle elenco campi Elenco campi Sviluppo 9/18 1pm-.>yannick 8
09/02 2:57 PM oracle uml modello preesistente base modello preesistente base Sviluppo 05/12 01:55-.>artaud 8
03/24 13:41 personale oracolo 8 personale oracolo 8 Software/Drivers 03/26 10:17am-.>yanban 7
07/04 02:10 AM installazione di oracle 8i windows xp Pb installazione di oracle 8i su windows XP Windows 01/22 15:32-.>loulou 7
02/12 3:59pm oracolo confronto ore confronto ore Sviluppo 09/02 2:03pm-.> Gilles M 5
08/03 12:04 pm oracle bd document.form.submit document.form.submit() Sviluppo 12/03 11:36am->renisaac 5
08/02 11:08 AM access import oracle data import oracle data Software/Drivers 10/02 6:27 pm-> casuale 4
11/11 5:06pm oracle developer developer Sviluppo 11/11 6:16pm-.>fagy 4
02/15 8:08pm oracle databases Domanda in ORACLE Databases Sviluppo 02/23 12:21 pm-.>Alex75 4
Discussione chiusa Problema risolto Oracle Niente più discussioni su “Oracle”

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *