Autoincrement Workaround für Oracle |
Diese Seite drucken |
Problemstellung Eine Tabelle
soll einen Primary Key bekommen, der automatisch beim Einfügen ein sog.
Autoincrement macht, also hochzählt.
In MySQL parametrisiert man dazu einfach nur das Feld mit "auto_increment" .
In Oracle gibt es diese Funktion nicht, deshalb behilft man sich in der Regel
mt diesem Workaround.
Lösungsansatz Man erzeugt zwei zusätzliche Datenbankobjekte, eine Sequence und einen Trigger. Die Sequenz erzeugt die einzusetzenden Werte, der before-insert-Trigger sorgt dafür, dass der neue Wert als erstes in der neuen Zeile landet.
Beispiel zur Lösung:
create table test (id number, testdata varchar2(255)); |
create sequence test_seq start with 1 increment by 1 nomaxvalue; |
Man kann statt "start with 1" auch eine andere Zahl einsetzen, mit der
begonnen werden soll.
Das "increment by 1" kann man eigentlich weglassen, weil es die default-Einstellung
ist. Ich wollte nur die Syntax zeigen, falls man z.B. größere Mindestabstände
zwischen den ids haben will.
Der Parameter "nomaxvalue" sagt der Seqeunce, das sie für immer und ewig
zu inkrementieren hat und nicht an irgendeinem Wert ein Reset machen soll.
Bestimmt gibt's irgendein physikalisches Limit in Oracle, ich kenne es aber
nicht.
Es kann übrigens durchaus sein, dass Zahlen 'übersprungen' werden,
weil sie von Oracle im Cache gehalten werden, um die Eindeutigkeit zu sichern.
Wenn man also lückenlos aufsteigende Nummern haben muss (wofür es
wenig gute Gründe gibt), wäre dieser Ansatz nicht ausreichend.
create trigger test_trigger before insert on test for each row begin select test_seq.nextval into :new.id from dual; end; / |
Ergänzende Befehle
Hier noch ein Paar Fragen, die man vielleicht manchmal stellen, will, um sich über seine Sequnces und Trigger zu informieren:
Wie kann ich alle meine Sequences und Trigger anzeigen lassen?
select sequence_name from user_sequences; |
Wie werde ich Trigger weider los, die ich erzeugt habe?
drop sequence test_seq; |
Man kann Trigger auch behalten und nur abschalten.
alter trigger test_trigger disable;
alter trigger test_trigger enable; |