„IDENTITY table clause“-Feature und Apex

Werbung
Die neue Datenbank
„IDENTITY table clause“-Feature und Apex
Alain Lacour und Arnaud Berbier, dbi-services
Der Artikel beschreibt, wie in Apex Primärschlüssel auf einer „IDENTITY“-Spalte abgebildet werden können, sodass
eine harmonische und performante Implementierung mit Oracle 12c gelingt.
Die neue Datenbank bietet für die
Tabellenerstellung die neue Klausel
„IDENTITY“ für eine nummerische
Spalte. Diese generiert bei Bedarf für jeden Spalten-Eintrag eine Sequenznummer. Der exakte Bedarf wird mit einem
Klausel-Parameter deklariert. Laut Dokumentation gibt es folgende Parameterwerte:
•
•
•
ALWAYS (Default)
BY DEFAULT
BY DEFAULT ON NULL
Je nach Klausel-Parameter werden
DML-Operationen unterschiedlich behandelt. Bemerkenswerterweise betrifft
diese neue Deklaration der Vorgabewerte teilweise auch „UPDATE-DML“. Dazu
ein Beispiel mit der Datenbank-Version
12.1.0.1.0 und Apex 4.2.0.00.27, das bereits in der Datenbank-Software enthalten ist. „ALWAYS“ verhindert, dass ein
Wert manuell eingetragen wird. Während der „INSERT“- oder „UPDATE“Vorgänge darf diese „IDENTITY“-Spalte
nicht adressiert werden. Bei Nichtbeachtung wird eine DML-Exception generiert (siehe Listing 1).
36 | www.doag.org
CREATE TABLE md_country
(
country_id
NUMBER GENERATED ALWAYS AS IDENTITY,
country_code CHAR (3 BYTE) NOT NULL,
country_name VARCHAR2 (200 BYTE) NOT NULL
);
Listing 1
CREATE TABLE md_country
(
country_id
NUMBER GENERATED BY DEFAULT AS IDENTITY,
country_code CHAR (3 BYTE) NOT NULL,
country_name VARCHAR2 (200 BYTE) NOT NULL
);
Listing 2
CREATE TABLE md_country
(
country_id
NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
country_code CHAR (3 BYTE) NOT NULL,
country_name VARCHAR2 (200 BYTE) NOT NULL
);
Listing 3
„BY DEFAULT“ bietet die Möglichkeit,
einen manuellen Wert anzugeben – außer „NULL“. So kann die Spalte während
„INSERT“- oder „UPDATE“-Operationen
manipuliert werden, solange ihr neuer
Wert nicht „NULL“ ist (siehe Listing 2).
„BY DEFAULT ON NULL“ bietet die
Möglichkeit, einen manuellen Wert
Die neue Datenbank
anzugeben – inklusive „NULL“. Sollte
die DML-Anweisung den „NULL“-Wert
für die „IDENTITY“-Spalte vorsehen,
erzwingt die Klausel „BY DEFAULT ON
NULL“ einen Wert aus der Sequenz.
So kann die Spalte bei „INSERT“- oder
„UPDATE“-Operationen adressiert werden, sogar mit „NULL“ als Wert in der
DML-Anweisung (siehe Listing 3). Das
ist sehr nützlich im Apex-Framework,
da Apex für Primary Keys vorzugsweise
Nummern verwendet.
Die Apex-Version, die mit Oracle
12c geliefert wird, unterstützt bereits
das neue Feature, sodass bereits im SQLWorkshop beim Aufsetzen einer Tabelle
die Primary Keys entsprechend deklariert
werden können. Dafür wurden ein neues Spalten-Attribut im Wizard „Create­
Table – Columns“ sowie eine neue Auswahlmöglichkeit auf der „Create Table
– Primary Key“-Seite hinzugefügt, was
im Folgenden beschrieben wird. Zuerst
wird die Spalte als „IDENTITY“ deklariert (siehe Abbildung 1).
Hinweis: Der Identity-Parameter kann
nur gesetzt werden, wenn der Datentyp
„NUMBER“ gewählt ist. Dann wird die
Primary-Key-Steuerung auf „Identity
Column“ gesetzt (siehe Abbildung 2).
Wenn man am Ende der Tabellendefinition die verschiedenen Objekte mittels SQL-Workshop betrachtet (siehe
Abbildung 3), entdeckt man Folgendes:
•
•
Tabelle
Die über eine „IDENTITY“-Klausel definierte Spalte besitzt einen DefaultWert, ermittelt aus einer Sequenz,
was auf einem anderen Weg nicht erlaubt wäre. So kann eine solche Spalte
erkannt werden, obwohl es keine explizite „IDENTITY“-Indikatoren gibt.
Sequenz
Bei einer Untersuchung der Sequenz
fällt der merkwürdige Name auf.
Anzumerken ist zudem, dass die Sequenz einen Default-Cache bekommen hat, wodurch Lücken bei Vergabe von „COUNTRY_ID“-Nummern
entstehen können, wenn von gleichzeitigen Sessions nur vereinzelte Einträge gemacht werden. Dieses Verhalten kann mit fortgeschrittener Syntax
der Tabellen-Definition laut OracleDokumentation genauer spezifiziert
werden (siehe Abbildungen 4 und 5).
Abbildung 1: Create Table Columns
Abbildung 2: Create Table Primary Key
Abbildung 3: Object Browser Table Definition
Abbildung 4: Object Browser Sequence Details
Abbildung 5: Object Browser Sequence Dependencies
DOAG News 05-2013 | 37
Die neue Datenbank
Abbildung 6: Create Page Primary Key
Abbildung 7: Error message
Abbildung 8: Edit Page Process
Hervorzuheben ist die verwirrende Tatsache, dass, obwohl die Sequenz durch
die Verwendung einer „IDENTITY“Klausel entstanden ist, die Tabelle
nicht in der Referenzliste erscheint.
Behandlung der „IDENTIY“ als Primary
Key in einem Formular
Damit das Zusammenspiel zwischen
dem neuen Feature und Apex getestet
werden kann, wurde eine DatenbankApplikation erstellt. Darin verwaltet ein Formular die Daten der „MD_
COUNTRY“-Tabelle.
Fall 1, mit „ALWAYS“-Parameter:
Bei der Wahl der Primary-Key-Quelle
(während der Erstellung des Formulars)
wurde manuell „Existing sequence“
gewählt. Auch die Sequenz, die zuvor
beim Aufsetzen der Tabelle generiert
worden ist, wurde Apex explizit in der
Drop-Down-Liste „Sequence“ bekanntgegeben (siehe Abbildung 6).
Beim Anlegen neuer Datensätze
mithilfe dieses Formulars kommt es
jedoch zu einer Fehlermeldung (siehe
Abbildung 7). Der fehlschlagende SQLCode liegt in der „Get PK“-Prozess-Anweisung, die von Apex für den Formularbereich „Page Processing“ generiert
wurde (siehe Abbildung 8).
Man erkennt im Quellcode, dass für
die Spalte ein Wert gesetzt wird. Eine
„IDENTITY ALWAYS“-Spalte verhindert so etwas bekanntlich und wirft
eine DML-Exception. Eine Daten-Än-
38 | www.doag.org
derung („update“, „delete“) kann weiterhin ohne Fehlermeldung durchgeführt werden. Wenn man hingegen
„Existing Trigger“ statt „Existing sequence“ wählt, werden die Daten auch
beim Erstellen richtig behandelt. Die
„Get PK“-Prozessanweisung wird bei
dieser Variante nicht generiert (siehe
Abbildung 9).
Obwohl kein Trigger existiert, behandelt Apex die Tabelle so, als ob es
einen gäbe. Somit kümmert sich Apex
gar nicht um die Verwaltung der Primary-Key-Spalte und überlässt das der
Datenbank. Glücklicherweise stört es
Apex nicht, dass es keinen Trigger gibt.
Im Fall 2, mit „BY DEFAULT“-Parameter, macht es keinen Unterschied,
ob man „Existing Trigger“ oder „Existing sequence“ während der Erstellung des Formulars wählt, denn hier
Abbildung 9: Create Page Primary Key
ist die Angabe eines Werts für die
„IDENTITY“-Spalte erlaubt, solange
von „NULL“ verschiedene Werte angegeben sind. So hat die „Get PK“-Prozessanweisung keinen Einfluss auf die
korrekte Arbeitsweise der „IDENTITY“Spalte, solange sie nicht geändert wird,
um den „NULL“-Wert zu verwenden.
Im Fall 3, mit „BY DEFAULT ON
NULL“-Parameter, ist es ebenfalls nebensächlich, ob man „Existing Trigger“
oder „Existing sequence“ verwendet.
Auch hier akzeptiert die „IDENTITY“Spalte Werte einschließlich „NULL“.
Die „Get PK“-Prozessanweisung findet
an dieser Stelle keinen Einsatz.
Anmerkung: Die dritte Wahl, „Custom PL/SQL function“, sollte für alle
Möglichkeiten und die „IDENTITY“Klausel-Parameter-Werte sorgfältig erwogen werden, bevor sie aufgesetzt wird.
Die neue Datenbank
Anzahl der eingefügten Datensätze
Zeitverbrauch der Identity-Variante (s)
Zeitverbrauch der Trigger-Variante (s)
100
0.0071
0.0232
1000
0.0486
0.2043
10000
0.4737
2.1988
100000
5.0842
21.9390
1000000
53.8582
217.648
Tabelle 1: Performance-Vergleich
Betrachtung der Performance
Eine Methode für die Handhabung von
ID-Spalten ist, dass man ihre Werte mithilfe eines „Before Insert“-Triggers automatisch generieren lässt. Dieser verwendet seinerseits ein Sequenzobjekt.
Das wird mit der neuen 12c-IDENTITY-Funktionalität verglichen und hinsichtlich der Performance untersucht.
Es wurden Ergebnisse für die vierfache
Geschwindigkeit der „IDENTITY“-Generierung im Vergleich zur Trigger-Lösung erzielt, unabhängig von der Anzahl der Datensätze (siehe Tabelle 1).
Fazit
Da für die Wahl der Primary-KeyQuelle die „Existing Trigger“-Option
in jedem Fall funktioniert, scheint sie
die bessere Wahl zu sein, sobald eine
„IDENTITY“-Spalte eine Verwendung
findet. Hinzu kommen die bemerkenswerten Performance-Vorteile der
„IDENTITY“-Spalte, die für ihre Verwendung als ID-Spalte in Oracle 12c
sprechen.
Alain Lacour
alain.lacour@
dbi-services.com
Arnaud Berbier
arnaud.berbier@
dbi-services.com
DOAG News 05-2013 | 39
Herunterladen