martinbulinski.de

Autoincrement in ORACLE simulieren Drucken E-Mail
  
Freitag, 23. Januar 2009 um 13:35

Leider gibt es in ORACLE keinen Datentypen AUTOINCREMENT, wie er in anderen Datenbanken (z.B. mysql) existiert. Sogar MS Access ist in der Lage, Spalten - typischerweise Primärschlüsselspalten - einen automatisch hochzählenden Wert zu vergeben.

In ORACLE kann man diesen Datentypen lediglich "simulieren", in dem man eine Sequence und einen Trigger benutzt.
Wenn man sein Datenmodell dahingehend überarbeiten möchte, bedeutet das, für jede auto-increment-Spalte eine eigene Sequence und einen eigenen Trigger zu programmieren. Das ist mir zuviel Arbeit. Anstelle dessen habe ich mir ein kleines PL/SQL-Programm geschrieben, das mir die Arbeit abnimmt und demonstriert, dass dynamische Programmierung nicht nur dynamisches SQL bedeutet, sondern auch Programme dynamisch generiert werden können.

 

Funktion

Die Procedure make_ai wird gefüttert mit dem Tabellennamen und der Spalte, die zum Primärschlüssel gemacht werden soll. Für die angebene Spalte wird ein Primary Key Constraint erzeugt, eine Sequence namens seq_<tabellenname> angelegt, die bei eins anfängt zu zählen und um eins inkrementiert. Zuguterletzt wird ein Trigger angelegt namens bi_<tabellenname>_autoinc, der bei jedem Insert-Versuch den nächsten Sequencewert selektiert und ihn in die Primärschlüsselspalte einfügt.

Grenzen/Fehlverhalten

  • Das Primärschlüssel-Constraint wird nicht benannt sondern kriegt einen ORACLE-eigenen Namen
  • Nur einspaltige Primärschlüssel werden erzeugt
  • Der Datentyp der Primärschlüsselspalte wird nicht geprüft. Sollte es sich um VARCHAR handeln, funktioniert die Triggeraktion dank automatischer Typkonvertierung weiterhin, spätestens bei DATE o.ä. löst der Trigger einen unbehandelten Fehler aus
  • Existiert schon ein Primärschlüssel, wird dieser nicht verändert, aber das Programm fährt fort mit dem Anlegen der Sequence und legt einen Trigger für die angegebene Spalte an. Das kann man auch als Feature benutzen, so daß auch NICHT-Primärschlüsselspalten mit dieser Art "autoincrement" versehen werden können
  • Existiert eine Sequence mit entspr. Namen bereits, wird diese verwendet und nicht neu angelegt
  • Ein eventueller Trigger mit gleichem Namen wird kommentarlos überschrieben
 create or replace procedure make_ai 
(tname varchar2, cname varchar2) is
begin
 begin
   execute immediate 'alter table '||tname||
' add primary key('||cname||')';
 exception
   when others then
-- Wenn der Primärschlüssel schon existiert, mach weiter
  if sqlcode=-2260 then
   null;
  else
   raise;
  end if;
 end;
 begin
   execute immediate 'create sequence seq_'||tname||
' start with 1 increment by 1';
 exception
   when others then
-- wenn die Sequence schon existiert, mach weiter
  if sqlcode=-955 then
   null;
  else
   raise;
  end if;
 end;
 begin
   execute immediate 'create or replace trigger bi_'||tname||
'_autoinc before insert on '||tname||' for each row'||
      ' begin select seq_'||tname||'.nextval into :new.'||
cname||' from dual;'||' end;';
 exception
   when others then
  raise;
 end;
end;
/

 

Aktualisiert ( Mittwoch, 28. Januar 2009 um 15:49 )
 
Benutzerbewertung: / 2
SchwachPerfekt 

Kommentar schreiben


Sicherheitscode
Aktualisieren

Anmeldung



Wer ist online

Wir haben 10 Gäste online