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

Come definire una chiave primaria di incremento automatico in Oracle

Con grande frustrazione degli amministratori di database in tutto il mondo, prima della versione 12c di Oracle a metà del 2014, Oracle semplicemente non aveva la capacità intrinseca di generare colonne con incremento automatico all'interno di uno schema di tabella. Sebbene le ragioni di questa decisione progettuale possano essere solo intuite, la buona notizia è che anche per gli utenti su sistemi Oracle precedenti, esiste una possibile soluzione alternativa per aggirare questa trappola e creare la propria colonna di chiave primaria con incremento automatico.

Creazione di una sequenza

Il primo passo è creare una SEQUENCE nel database, che è un oggetto dati a cui più utenti possono accedere per generare automaticamente valori incrementati. Come discusso nella documentazione, una sequenza in Oracle impedisce la creazione simultanea di valori duplicati perché più utenti sono effettivamente costretti a "fare a turno" prima che ogni elemento sequenziale venga generato.

Ai fini della creazione di una chiave primaria univoca per una nuova tabella, dobbiamo prima CREATE la tabella che useremo:

CREATE TABLE books (
  id      NUMBER(10)    NOT NULL,
  title   VARCHAR2(100) NOT NULL
);

Quindi dobbiamo aggiungere una PRIMARY KEY vincolo:

ALTER TABLE books
  ADD (
    CONSTRAINT books_pk PRIMARY KEY (id)
  );

Infine, creeremo la nostra SEQUENCE che verrà utilizzato in seguito per generare effettivamente il valore univoco auto incrementato.

CREATE SEQUENCE books_sequence;

Aggiunta di un trigger

Mentre abbiamo il nostro tavolo creato e pronto per l'uso, la nostra sequenza finora è solo seduta lì ma non viene mai utilizzata. Qui è dove TRIGGERS entra.

Simile a un event nei moderni linguaggi di programmazione, un TRIGGER in Oracle è una procedura memorizzata che viene eseguita quando si verifica un evento particolare.

Tipicamente un TRIGGER verrà configurato per attivarsi quando una tabella viene aggiornata o un record viene eliminato, fornendo un po' di pulizia quando necessario.

Nel nostro caso, vogliamo eseguire il nostro TRIGGER prima di INSERT nei nostri books tabella, assicurando la nostra SEQUENCE viene incrementato e quel nuovo valore viene passato alla nostra colonna della chiave primaria.

CREATE OR REPLACE TRIGGER books_on_insert
  BEFORE INSERT ON books
  FOR EACH ROW
BEGIN
  SELECT books_sequence.nextval
  INTO :new.id
  FROM dual;
END;

Qui stiamo creando (o sostituendo se esiste) il TRIGGER denominato books_on_insert e specificando che vogliamo che il trigger si attivi BEFORE INSERT si verifica per i books tabella e per essere applicabile a tutte le righe in essa contenute.

Il "codice" del trigger stesso è abbastanza semplice:SELECT il valore incrementale successivo dal nostro books_sequence creato in precedenza SEQUENCE e inserendolo nel :new record dei books tabella nel .id specificato campo.

Nota:il FROM dual parte è necessaria per completare una query corretta ma è effettivamente irrilevante. Il dual table è solo una singola riga fittizia di dati e viene aggiunta, in questo caso, solo così può essere ignorata e possiamo invece eseguire la funzione di sistema del nostro trigger piuttosto che restituire dati di qualche tipo.

Colonne IDENTITY

IDENTITY le colonne sono state introdotte in Oracle 12c, consentendo una semplice funzionalità di incremento automatico nelle versioni moderne di Oracle.

Usando il IDENTITY colonna è funzionalmente simile a quella di altri sistemi di database. Ricreare i nostri books sopra schema della tabella nel moderno Oracle 12c o versioni successive, useremmo semplicemente la seguente definizione di colonna.

CREATE TABLE books (
  id      NUMBER        GENERATED BY DEFAULT ON NULL AS IDENTITY,
  title   VARCHAR2(100) NOT NULL
);