Bei einem BLOB sind beispielsweise 128 TB möglich. Die einzige Grenze ist hier das Betriebssystem, auf dem Oracle läuft. Hat man die Datentyphürde überwunden, wird der MySQL-verwöhnte Datenbankentwickler erst richtig gefoltert: Es gibt weder LIMIT, noch AUTOINCREMENT. ENUM/SET? Sucht man vergebens. GROUP_CONCAT? Fehlanzeige! Entweder sind die schönsten Funktionen MySQL-proprietär, oder Oracle unterstützt den aktuellen SQL-Standard an einigen Stellen noch nicht – wobei hier gesagt werden muss, dass auch MySQL noch nicht vollständig standardkonform arbeitet. Um analog zu MySQLs AUTOINCREMENT fortlaufende Nummerierungen für beispielsweise einen Primary Key zu vergeben, müssen wir in Oracle Sequenzen und Trigger bemühen. Wir legen für eine Tabelle TABLE1 zunächst eine Sequenz an:
CREATE SEQUENCE TABLE1_SEQ INCREMENT BY 1 START WITH 1
Im Anschluss können wir einen Trigger anlegen (Listing 1).
CREATE TRIGGER TABLE1_TRG
BEFORE INSERT ON TABLE1
FOR EACH ROW
BEGIN
SELECT TABLE1_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
END;
Beim Anlegen des Triggers müssen die entsprechende Tabelle (TABLE1), die Sequenz (TABLE1_SEQ) und die Spalte, auf die man den Trigger legen möchte (ID in der vorletzten Zeile), angegeben werden.
Tabelle 2: Systemanforderungen
|
Min. RAM |
Min. HDD |
Windows 32 bit |
1 GB |
4,76 GB |
Windows 64 bit |
5,22 GB |
Unix/Linux 32 bit |
Standard Edition: 4,82 GB Enterprise Edition: 5,07 GB |
Unix/Linux 64 bit |
Standard Edition: 5,22 GB Enterprise Edition: 6,03 GB |
Von hinten durch die Brust ins Auge
Zugegeben, das war jetzt schon etwas umständlich. Richtig durchgeknallt wird es, wenn man nur seitenweise Auszüge aus einem Ergebnis erhalten möchte. Mit MySQL geht das so, wie in Listing 2 gezeigt.
SELECT LAST_NAME, FIRST_NAME
FROM EMPLOYEES
ORDER BY LAST_NAME ASC
LIMIT 5, 5
Ergebnis
|
LAST_NAME |
FIRST_NAME |
1 |
Baida |
Shelli |
2 |
Banda |
Amit |
3 |
Bates |
Elizabeth |
4 |
Bell |
Sarah |
5 |
Bernstein |
David |
In Oracle gibt es zwar die Pseudodatenspalte ROWNUM. Aber wenn man nun denkt, das würde reichen, irrt man sich gewaltig:
SELECT LAST_NAME, FIRST_NAME
FROM EMPLOYEES
WHERE ROWNUM BETWEEN 6 AND 10
ORDER BY LAST_NAME ASC
Führt man dieses Statement aus, erhält man: Nichts! Was ist passiert? Oracle weist ROWNUM 1 immer der ersten Zeile zu. Durch die Anweisung … BETWEEN 6 … teile ich der Datenbank nun mit, dass sie alle Zeilen mit einer ROWNUM kleiner 6 „wegwerfen“ soll – was sie auch tut. Allerdings erhalten dann die nächsten fünf Zeilen wiederum ROWNUM 1 bis 5, werden gelöscht und so weiter. Das passiert so lange bis keine Datensätze mehr vorhanden sind. Das ist auch dann problematisch, wenn man mit ROWNUM 1 beginnt. Bei den obigen Beispielen würden zwar scheinbar die gleichen Daten zurückgegeben, ändert man aber die Sortierung auf FIRST_NAME, erhält man komplett unterschiedliche Ergebnisse:
MySQL:
|
LAST_NAME |
FIRST_NAME |
1 |
Fripp |
Adam |
2 |
Walsh |
Alana |
3 |
Errazuriz |
Alberto |
4 |
Khoo |
Alexander |
5 |
Hunold |
Alexander |
Oracle:
|
LAST_NAME |
FIRST_NAME |
1 |
Austin |
David |
2 |
Abel |
Ellen |
3 |
Baer |
Hermann |
4 |
Atkinson |
Mozhe |
5 |
Ande |
Sundar |
Der Grund hierfür ist die unterschiedliche Position der ORDER-Anweisung. Bei MySQL wird erst sortiert, bevor LIMIT ausgeführt wird, bei Oracle wird erst nach ROWNUM eingegrenzt und dann sortiert. Die Lösung: Wir schreiben unser Statement ohne Limitierung, aber mit Sortierung, setzen das in ein Subselect, in dem die ROWNUM angefügt wird und können dann, da die ROWNUM nun über eine ganz normale Spalte verfügbar ist, in einem nächsten Subselect mit BETWEEN nach Belieben eingrenzen (Listing 3).
SELECT q2.* FROM (
SELECT ROWNUM AS ROWNUMBER, q1.* FROM (
SELECT LAST_NAME, FIRST_NAME
FROM EMPLOYEES
ORDER BY FIRST_NAME ASC
) q1
) q2 WHERE q2.ROWNUMBER BETWEEN 1 AND 5
Ergebnis
|
ROWNUMBER |
LAST_NAME |
FIRST_NAME |
1 |
1 |
Fripp |
Adam |
2 |
2 |
Walsh |
Alana |
3 |
3 |
Errazuriz |
Alberto |
4 |
4 |
Khoo |
Alexander |
5 |
5 |
Hunold |
Alexander |
Weiter mit: Teil 4
Alle Teile: Teil 1, Teil 2, Teil 3, Teil 4, Teil 5, Teil 6
Hinterlasse einen Kommentar
Hinterlasse den ersten Kommentar!