Til stor frustration for databaseadministratorer over hele verden, før Oracle version 12c i midten af 2014, havde Oracle simpelthen ingen iboende evne til i sagens natur at generere automatiske inkrementeringskolonner i et tabelskema. Selvom der kun kan gættes på årsagerne til denne designbeslutning, er den gode nyhed, at selv for brugere på ældre Oracle-systemer er der en mulig løsning til at omgå denne faldgrube og oprette din egen automatisk øgede primærnøglekolonne.
Oprettelse af en sekvens
Det første trin er at oprette en SEQUENCE
i din database, som er et dataobjekt, som flere brugere kan få adgang til for automatisk at generere øgede værdier. Som diskuteret i dokumentationen forhindrer en sekvens i Oracle, at duplikerede værdier oprettes samtidigt, fordi flere brugere effektivt er tvunget til at "skiftes", før hvert sekventielt element genereres.
For at skabe en unik primær nøgle til en ny tabel skal vi først CREATE
tabellen, vi skal bruge:
CREATE TABLE books (
id NUMBER(10) NOT NULL,
title VARCHAR2(100) NOT NULL
);
Dernæst skal vi tilføje en PRIMARY KEY
begrænsning:
ALTER TABLE books
ADD (
CONSTRAINT books_pk PRIMARY KEY (id)
);
Til sidst opretter vi vores SEQUENCE
som vil blive brugt senere til rent faktisk at generere den unikke, automatisk forøgede værdi.
CREATE SEQUENCE books_sequence;
Tilføjelse af en trigger
Mens vi har vores bord lavet og klar til at gå, sidder vores sekvens indtil videre bare der, men bliver aldrig taget i brug. Det er her TRIGGERS
kom ind.
Svarende til en event
i moderne programmeringssprog, en TRIGGER
i Oracle er en lagret procedure, der udføres, når en bestemt hændelse indtræffer.
Typisk en TRIGGER
vil blive konfigureret til at udløse, når en tabel opdateres, eller en post slettes, hvilket giver en smule oprydning, når det er nødvendigt.
I vores tilfælde ønsker vi at udføre vores TRIGGER
før INSERT
i vores books
tabel, hvilket sikrer vores SEQUENCE
øges, og den nye værdi sendes til vores primære nøglekolonne.
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;
Her er vi ved at oprette (eller erstatte, hvis den findes) TRIGGER
navngivet books_on_insert
og angive, at vi ønsker, at udløseren skal udløse BEFORE INSERT
forekommer for books
tabel, og skal være anvendelig på alle rækker deri.
"Koden" for selve triggeren er ret simpel:Vi SELECT
den næste trinvise værdi fra vores tidligere oprettede books_sequence
SEQUENCE
, og indsætte det i :new
registrering af books
tabel i den angivne .id
felt.
Bemærk:FROM dual
del er nødvendig for at fuldføre en korrekt forespørgsel, men er faktisk irrelevant. dual
tabel er kun en enkelt dummy række af data og tilføjes, i dette tilfælde, bare så den kan ignoreres, og vi i stedet kan udføre systemfunktionen af vores trigger i stedet for at returnere data af en eller anden art.
IDENTITY-kolonner
IDENTITY
kolonner blev introduceret i Oracle 12c, hvilket giver mulighed for enkel automatisk stigningsfunktionalitet i moderne versioner af Oracle.
Brug af IDENTITY
kolonne er funktionelt lig den i andre databasesystemer. Genskaber vores ovenstående books
tabelskema i moderne Oracle 12c eller nyere, ville vi blot bruge følgende kolonnedefinition.
CREATE TABLE books (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
title VARCHAR2(100) NOT NULL
);