vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Tag 12

Komplexe Datenbankabfrage n

Bisher haben Sie gesehen, welche Möglichkeiten UltraDev für einfache Abfragen bietet. Sie können Informationen aus der Datenbank abrufen und dann anzeigen. In der Regel sollte dieser einfache Abfragemodus für Ihre Site völlig ausreichend sein. Für komplexe Applikationen brauchen Sie jedoch die Leistungsstärke von SQL für die Verarbeitung Ihrer Programmlogik. Dieses Kapitel bietet Ihnen eine kurze SQL-Lehrstunde, in der Sie erfahren, wie Sie die Leistung Ihres Datenbankservers wirklich ausnutzen können. Heute geht es um die folgenden Themen:

12.1 Wozu brauchen wir SQL?

In den vergangenen Kapiteln haben Sie die einfachen Abfragen und Serververhalten von UltraDev genutzt, um Site-Fragmente mit dynamischer Funktionalität zu entwickeln. Leider ist mit diesen eingebauten Verhalten nur eine begrenzte Flexibilität zu erzielen. Wenn Sie einem Benutzer beispielsweise ermöglichen, in einem Formular seinen Vor- und Nachnamen einzugeben, und die Datenbank nach diesen Namen durchsuchen wollen, ist das mit einer einfachen UltraDev-Abfrage nicht möglich.

Einfache Abfragen wie die in Abbildung 12.1 gezeigte ermöglichen nur eine Auswahl von Daten, die auf einem einzigen dem Verhalten übergebenen Parameter basieren. Falls Sie innerhalb einer einfachen Abfrage mehrere Informationsabschnitte nutzen wollen, haben Sie Pech gehabt.

Abbildung 12.1:  Eine einfache Abfrage ist auf eine auf einem einzigen Eingabeparameter basierende Datenauswahl beschränkt.

Und das ist nur die Spitze des Eisbergs. Wenn Sie dagegen das SQL direkt verwenden, können Sie Datensätze nach mehreren Attributen auswählen, nach mehreren Attributen sortieren, mathematische und logische Funktionen für Feldwerte ausführen, Informationen zufällig anzeigen - und vieles andere mehr.

Dieses Kapitel soll Ihnen ein praktisches Wissen über SQL verschaffen, sodass Sie wirklich komplexe Applikationen entwickeln können, ohne die Bequemlichkeit der UltraDev- Umgebung verlassen zu müssen. Obwohl UltraDev die Möglichkeit bietet, ausschließlich durch verschiedene Mausklicks komplexe Abfragen anzulegen, werden Sie es einfacher finden, die Abfragen unmittelbar in die Applikation einzugeben, wenn Sie sich erst einmal daran gewöhnt haben, SQL manuell zu schreiben.

Falls Ihnen der Begriff SQL neu ist: Er steht für Structured Query Language. SQL ist eine Sprache, die zur Abfrage relationaler Datenbanksysteme entwickelt wurde. Sie ist zum allgemein akzeptierten Standard geworden und wird in fast allen kommerziellen Datenbanksystemen verwendet. SQL findet sich ebenso in mehreren Open Source-Applikationen, wie beispielsweise MySQL, das Sie für die Beispiele in diesem Buch verwenden werden.

Zunächst betrachten wir das SQL, mit dem eine Datenbank erstellt wird. Sie kennen die dafür erforderlichen SQL-Anweisungen bereits, aber wissen Sie auch, wie Sie sie selbst schreiben? Nachdem Sie die grundlegenden Werkzeuge für Datenbanken, Tabellen und andere Strukturen kennen gelernt haben, werden wir uns mit Abfragen beschäftigen. Stellen Sie sicher, dass Sie einen Datenbankserver installiert haben, bevor Sie mit diesem Kapitel fortfahren - Sie müssen die Befehle in Ihrer Serverkonsole eingeben, damit Sie sie nachvollziehen können.

Falls Sie Access einsetzen, können Sie auch SQL verwenden, um eine Abfrage zu entwickeln. Legen Sie eine neue Abfrage an und wählen Sie im Ansicht-Menü den Eintrag SQL-Ansicht. In das angezeigte Dialogfeld geben Sie das SQL direkt ein. Microsoft Access ist jedoch kein vollfunktionales SQL-System, deshalb kann es sein, dass manche Abfragen nicht funktionieren.

12.2 Die Datenbankobjekte

Bevor wir mit der Entwicklung von SQL beginnen können, müssen vier primäre Objekte definiert werden. Das erscheint Ihnen vielleicht trivial, wenn Sie die Arbeit mit Datenbanken gewohnt sind, aber wenn Ihnen das alles neu ist, kann es vielleicht zur Klärung der Dinge beitragen. In UltraDev haben Sie Zugriff auf vier externe Strukturen:

Das Datenbanksystem, das Sie in allen hier gezeigten Beispielen verwenden werden, unterstützt keine gespeicherten Prozeduren oder Ansichten. Diese beiden SQL-Elemente sind praktisch, aber selten wirklich notwendig. Beim Lesen der nächsten Kapitel können Sie die komplexen Abfragen, die Sie heute kennen lernen werden, natürlich jederzeit in Ansichten umwandeln.

12.3 Datenbanken und Tabellen anlegen

Der erste Schritt bei der Arbeit mit einem Datenbanksystem ist, die eigentliche Datenbank anzulegen, also den Container. Er nimmt alle Tabellen, Ansichten usw. für die gesamte Datensammlung auf. Wenn Sie also von einer Datenbank sprechen, dann beziehen Sie sich auf eine Datensammlung und nicht auf einzelne Datenfragmente.

Um eine Datenbank anzulegen, brauchen Sie einen installierten SQL-Server und die Datenbank-Befehlszeile. Weitere Informationen darüber, wie Sie an diese Ausgangsposition gelangen, entnehmen Sie bitte der Dokumentation Ihres Servers. Wenn Sie ein visuell orientiertes Werkzeug verwenden, sollten Sie die äquivalenten Funktionen zu den folgenden Befehlen suchen:

create database <datenbankname>;

Weil SQL-Anweisungen häufig sehr groß werden, erlauben die meisten Systeme, dass sie über mehrere Zeilen geschrieben werden und verwenden ein Abschlusszeichen, an dem sie erkennen, dass die Anweisung fertig zur Ausführung ist. Bei MySQL, das für die Beispiele in diesem Buch häufig verwendet wird, ist das Semikolon dieses Abschlusszeichen.

Der Befehl create erzeugt eine völlig leere Datenbank. Nachdem eine Datenbank angelegt wurde, müssen Sie Ihrem Datenbankserver möglicherweise explizit mitteilen, dass Sie Ihre Datenbank benutzen wollen. Wie Sie das machen, ist von Ihrem System abhängig, etwa wie folgt:

use <datenbankname>;

Wir beginnen mit einer einfachen Angestellten-Datenbank:

mysql> create database employee;
Query OK, 1 row affected (0.07 sec)

mysql> use employee;
Database changed
mysql>

Um die soeben definierte Datenbank zu löschen, verwenden Sie den Befehl drop:

drop database <datenbankname>;

Beachten Sie auch hier, dass die Datenbank die Hülle für alle Tabellen ist, die Daten enthalten können. Wenn Sie mit dem Befehl drop eine Datenbank löschen, löschen Sie damit auch alle darin enthaltenen Tabellen, Ansichten und anderen Strukturen, ebenso wie die darin enthaltenen Daten. Seien Sie also vorsichtig!

Nachdem eine Datenbank angelegt wurde, müssen Sie die internen Tabellen einrichten, um die Daten aufzunehmen, die Sie speichern möchten.

Zum Anlegen einer Tabelle verwenden Sie ebenfalls den Befehl create, um dem System mitzuteilen, welche Art von Daten Sie speichern wollen - wenn überhaupt.

create table <tabellenname> (<spalten...>, <spalten...>)

Angenommen, wir legen Tabellen für die Angestellten-Datenbank an, die eine Liste der Angestellten und eine Liste der Jobnamen enthalten:

create table tblemployee (
employeeID int not null,
titleID int,
age int,
salary float,
firstname varchar(50),
lastname varchar(50),
primary key (employeeID)
);

create table tbljobtitle (
titleID int not null,
description varchar(250),
lowersal float,
uppersal float,
primary key (titleID)
);

Die Felder uppersal und lowersal geben Informationen über das Höchst- und das Mindestgehalt für eine bestimmte Jobbeschreibung an.

Die Syntax create table <tabellenname> ist zwar ohne weitere Erklärung verständlich, aber die Bedeutung der Felder ist vielleicht weniger offensichtlich. Der erste Wert in einer Felddefinition ist der Name des Feldes, wie beispielsweise employeeID oder titleID. Der zweite Wert gibt den Datentyp für dieses Feld an, gefolgt von speziellen Modifizierern.

Datentypen

Jetzt betrachten wir einige der gebräuchlichen Datentypen, denen Sie in Ihren UltraDev- Projekten immer wieder begegnen werden:

In einigen Datenbanksystemen stehen noch sehr viel mehr Datentypen zur Verfügung. Beispielsweise werden unter dem Namen tinyint sehr kleine ganze Zahlen unterstützt, oder es gibt Felder des Datentyps datetime, die das Datum und die Zeit speichern.

Wenn Sie bereits mit Datenbanken gearbeitet haben, wollen Sie möglicherweise binäre Felder verwenden, um binäre Informationen - wie beispielsweise Fotos - in eine Datenbank einzubetten. Leider ist das in UltraDev momentan nicht möglich. Sie können jedoch die Namen von binären Dateien (wie beispielsweise Bilddateien) speichern und dann in UltraDev auf diese Dateien verweisen.

Neben den Felddefinitionen gibt es noch zwei Informationsabschnitte. Die erste Information ist das Modifizierer-Attribut not null. Durch das Anfügen von not null am Ende eines Feldnamens wird dem Datenbanksystem mitgeteilt, dass das Feld keinen Null- Wert enthalten darf, d.h., es muss irgendeine Information enthalten. Das ist nicht dasselbe wie eine leere Zeichenkette (»«), wobei es sich ja um Information handelt. Ein null-Wert bedeutet das völlige Fehlen von Daten.

Die zweite Information für die Felddeklaration ist der Primärschlüssel. Wie Sie in Kapitel 6 erfahren haben, wird ein Primärschlüssel verwendet, um einen Informationsabschnitt in einer Tabelle eindeutig zu identifizieren. Dieses Feld (bzw. diese Felder) muss offensichtlich Daten enthalten, deshalb wird es in der Regel in der zugehörigen Tabellendefinition als not null deklariert.

Viele Datenbanksysteme setzen voraus, dass alle im Primärschlüssel verwendeten Felder implizit als not null definiert sind. MySQL folgt diesem Ansatz nicht und erzwingt, den Primärschlüsselfeldern not null hinzuzufügen.

Um Kompatibilität zwischen verschiedenen Datenbanksystemen zu bewahren, sollten Sie not null in Ihre Tabellendefinitionen aufnehmen.

Ähnlich dem Befehl zum Löschen von Datenbanken verwenden Sie den folgenden Befehl, um eine Tabelle vollständig aus einer Datenbank zu entfernen:

drop table <tabellenname>

Damit werden die Tabelle und alle darin enthaltenen Informationen aus der Datenbank gelöscht. Wir haben noch keine Daten in die Tabellen eingetragen - wenn Sie möchten, probieren Sie also den drop-Befehl jetzt aus.

12.4 Daten eintragen/ändern

Die Eingabe von Daten in eine Datenbank ist relativ einfach - Sie verwenden dazu den Befehl insert. Es gibt zwei Möglichkeiten, Daten einzutragen - eine zum Einfügen eines partiellen Datensatzes und eine andere zum Einfügen eines fertigen Datensatzes in eine Tabelle:

insert into <tabellenname> [(<feld1,feld2,...>)] values 
<'wert1','wert2',...>)

Mit der ersten Variante des Befehls (d.h. mit Angabe einer Feldnamenliste) können Sie eine Liste mit durch Kommas voneinander getrennten Feldnamen und den zugehörigen Daten anlegen. Die zweite Variante setzt voraus, dass Sie alle Felder in einem Schritt ausfüllen und die Werte dabei in der Reihenfolge angeben, wie sie beim Anlegen der Tabelle definiert wurden.

Die erste Form des INSERT-Befehls ist manchmal verwirrend, weil sie den Eindruck vermittelt, Sie könnten beliebige Daten zu beliebigen Zeitpunkten speichern. In der Realität müssen Sie natürlich die Regeln für den Eintrag von not null einhalten, die Sie beim Anlegen der Tabelle festgelegt haben.

Darüber hinaus können Sie den INSERT-Befehl nicht mit zusätzlichen Feldnamen aufrufen, um Informationen zu ergänzen, die Sie beim ersten Mal nicht angegeben haben. Dazu müssen Sie entweder den partiellen Datensatz löschen und ihn mit den zusätzlichen Informationen neu anlegen, oder die Feldwerte mithilfe des UPDATE-Befehls ändern.

Versuchen Sie jetzt, einige Datensätze in die beiden zuvor erstellten Tabellen einzufügen:

insert into tblemployee values ('1','2','35','24000.75','Maddy','Dogg');
insert into tblemployee values ('2','4','21','1105.25','Peter','Paul');
insert into tblemployee values ('3','2','22','10812.90','Mary','Ann');
insert into tblemployee values ('4','3','68','300000.92','John','Ray');
insert into tblemployee values ('5','3','52','150321.00','Klaus','Meine');
insert into tblemployee values ('6','4','52','1000.00','Herman','Rarebell');
insert into tblemployee values ('7','1','50','128312.92','Steve','Jobs');
insert into tblemployee values ('8','3','27','200000.55','Robyn','Ness');
insert into tblemployee values ('9','3','28','300001.19','Anne','Groves');
insert into tblemployee values ('10','4','23','2435.12','Julie','Vujevich');

insert into tbljobtitle values (1,'President/CEO','100000.00','250000.00');
insert into tbljobtitle values (2,'Manager','10000.00','25000.00');
insert into tbljobtitle values (3,'Programmer','300000.00','350000.00');
insert into tbljobtitle values (4,'Designer','1000.00','5000.00');

Diese Daten tragen 10 Angestellte in die Angestellten-Datenbank ein und ordnen ihnen eine von vier Berufsbezeichnungen für ihre Position im Unternehmen zu. Später werden wir betrachten, wie wir gleichzeitig Daten aus beiden Tabellen abrufen.

Eine erweiterte Funktion des INSERT-Befehls ist die Verwendung einer select-Anweisung (eine Abfrage), die den Teil values (<wert1...>) des INSERT-Befehls ersetzt. Auf diese Weise können Sie Daten, die aus anderen Tabellen abgefragt werden, direkt in eine andere Tabelle einfügen. Weitere Informationen darüber finden Sie im Abschnitt über die select-Syntax.

Nachdem Sie Daten in Ihr System eingetragen haben, können Sie sie mithilfe von zwei Befehlen ändern: update und delete.

Daten aktualisieren

update macht genau das, was sein Name ausdrückt - es aktualisiert existierende Datensätze in der SQL-Datenbank. Das Format eines update-Befehls ist einfach und dennoch leistungsfähig:

update <tabellenname> SET <feldname 1>=<ausdruck 1>,
<feldname 2>=<ausdruck 2>,<feldname n>=<ausdrck n>
[WHERE <suchausdruck>]

Für update müssen Sie einen Tabellennamen sowie die Namen der zu aktualisieren Felder und ihre neuen Werte angeben. Beispielsweise handelt es sich bei der folgenden Anweisung um eine partielle Aktualisierung, wobei in der Angestellten-Tabelle nur der Inhalt der Felder für den Nachnamen und das Alter geändert wird:

update tblemployee set lastname='Rantherpeen',age='62'

Das ist ein Teil des update-Befehls, aber was fehlt? Es sollte offensichtlich sein, dass eine Möglichkeit fehlt, die Datensätze zu identifizieren, die aktualisiert werden sollen. Wenn Sie diesen Befehl auf dem Datenbankserver ausführen und dann die Ergebnisse anzeigen, sind Sie vielleicht überrascht:

mysql> update tblemployee set lastname='Rantherpeen',age='62';

Query OK, 10 rows affected (0.13 sec)
Rows matched: 10 Changed: 10 Warnings: 0

mysql> select * from tblemployee;
+------------+---------+------+---------+-----------+-------------+
| employeeID | titleID | age | salary | firstname | lastname |
+------------+---------+------+---------+-----------+-------------+
| 1 | 2 | 62 | 24000.8 | Maddy | Rantherpeen |
| 2 | 4 | 62 | 1105.25 | Peter | Rantherpeen |
| 3 | 2 | 62 | 10812.9 | Mary | Rantherpeen |
| 4 | 3 | 62 | 300001 | John | Rantherpeen |
| 5 | 3 | 62 | 150321 | Klaus | Rantherpeen |
| 6 | 4 | 62 | 1000 | Herman | Rantherpeen |
| 7 | 1 | 62 | 128313 | Steve | Rantherpeen |
| 8 | 3 | 62 | 200001 | Robyn | Rantherpeen |
| 9 | 3 | 62 | 300001 | Anne | Rantherpeen |
| 10 | 4 | 62 | 2435.12 | Julie | Rantherpeen |
+------------+---------+------+---------+-----------+-------------+
10 rows in set (0.00 sec)

Das war wirksam - aber vielleicht nicht wie ursprünglich vorgesehen. Wenn Sie das Beispiel nachvollzogen haben, fügen Sie die Daten noch einmal neu ein, um diese fehlgeschlagene Datenaktualisierung schnell verschwinden zu lassen.

Daraus sollten Sie lernen, dass SQL beim Fehlen einer where-Klausel davon ausgeht, dass Sie alle Datensätze ansprechen wollen. Dasselbe gilt für die Anweisungen delete und select, die Sie in ein paar Minuten kennen lernen werden.

Die nächste Frage ist, wie Sie den Suchausdruck für die where-Klausel formulieren. Der Suchausdruck muss eine richtige oder falsche Bedingung ergeben, die angibt, ob ein Datensatz ausgewählt werden soll oder nicht. Zum Anlegen eines Suchausdrucks verwenden Sie normalerweise die boolesche Algebra:

<feldname> = <wert> - Wählt Datensätze abhängig von einem direkten Vergleich mit einem Wert aus.

<feldname> > <wert> - Wählt Datensätze aus, deren Feldwert größer als ein vorgegebener Wert ist.

<feldname> < <wert> - Wählt Datensätze aus, deren Feldwert kleiner als ein vorgegebener Wert ist.

<feldname> >= <wert> - Wählt Datensätze aus, deren Feldwert größer oder gleich einem vorgegebenen Wert ist.

<feldname> <= <wert> - Wählt Datensätze aus, deren Feldwert kleiner oder gleich einem vorgegebenen Wert ist.

<feldname> LIKE <wert> - Wählt Datensätze entsprechend einem einfachen SQL- Musterschema aus. Das Zeichen % steht für eine beliebige Anzahl an Zeichen, während _ für genau ein Zeichen steht. Weitere Informationen über die Mustersuche finden Sie in Ihrer Datenbankdokumentation.

Die folgenden grundlegenden Ausdrücke können für komplexere Suchen kombiniert werden:

NOT <ausdruck> - Ergibt true, wenn der Ausdruck false ergibt.

<ausdruck> OR <ausdruck> - Ergibt true, wenn einer der Ausdrücke true ergibt.

<ausdruck> AND <ausdruck> - Ergibt true, wenn beide Ausdrücke true ergeben.

(<ausdruck>) - Mithilfe von Klammern kombinieren Sie Ausdrücke oder erzwingen eine andere Auswertungsreihenfolge.

Um das Ganze noch komplizierter zu machen, können Sie eine Vielzahl mathematischer und Zeichenketten-Funktionen von SQL anwenden, um Feldwerte innerhalb von Ausdrücken zu manipulieren - alles dynamisch. Wenn Sie beispielsweise die Felder a und b haben, könnten Sie einen Ausdruck konstruieren, der prüft, ob die Gesamtsumme der Feldwerte größer als 10 ist, indem Sie "a+b > 10" als Suchausdruck angeben.

Jedes Datenbanksystem unterstützt unterschiedliche Funktionalitätsebenen, lesen Sie deshalb die genauen Spezifikationen in Ihrer Datenbankdokumentation nach. Wir werden heute einige der gebräuchlicheren Funktionen verwenden, aber möglicherweise stehen Ihnen sehr viel mehr zur Verfügung.

Jetzt zurück zur Aktualisierung der Angestelltentabelle. Sie wissen jetzt, wie man einen WHERE-Suchausdruck formuliert. Welches SQL braucht man, um den Datensatz für »Mary Ann« mit einem neuen Nachnamen und einem neuen Alter zu versehen?

Damit sollte es funktionieren:

update tblemployee set lastname='Rantherpeen',age='62' 
where firstname='Mary' and lastname='Ann';

Mit den Daten aus der Angestelltentabelle hätten Sie den Suchausdruck auch so formulieren können, dass nur das Feld lastname auf den Wert »Ann« überprüft wird. Aber wie Sie in Kapitel 6 erfahren haben, sollten Sie sich nie auf den Nachnamen einer Person als eindeutigen Bezeichner verlassen. In einer Datenbank mit einigen Hunderttausend Angestellten würden damit sicherlich mehrere Übereinstimmungen gefunden.

Der hier verwendete update-Befehl ist aber auch nicht besser. Wenn Sie in einem Produktionssystem einen einzigen Datensatz (und nicht eine Gruppe von Datensätzen) aktualisieren wollen, sollten Sie Ihren Suchausdruck unbedingt auf dem Primärschlüssel für die Tabelle basieren lassen.

Nachdem Sie den Datensatz eingefügt haben, kann er in der Tabelle tblemployee angezeigt werden:

mysql> update tblemployee set lastname='Rantherpeen',age='62' 
where firstname='Mary' and lastname='Ann';

Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from tblemployee;

+------------+---------+------+---------+-----------+-------------+
| employeeID | titleID | age | salary | firstname | lastname |
+------------+---------+------+---------+-----------+-------------+
| 1 | 2 | 35 | 24000.8 | Maddy | Dogg |
| 2 | 4 | 21 | 1105.25 | Peter | Paul |
| 3 | 2 | 62 | 10812.9 | Mary | Rantherpeen |
| 4 | 3 | 68 | 300001 | John | Ray |
| 5 | 3 | 52 | 150321 | Klaus | Meine |
| 6 | 4 | 52 | 1000 | Herman | Rarebell |
| 7 | 1 | 50 | 128313 | Steve | Jobs |
| 8 | 3 | 27 | 200001 | Robyn | Ness |
| 9 | 3 | 28 | 300001 | Anne | Groves |
| 10 | 4 | 23 | 2435.12 | Julie | Vujevich |
+------------+---------+------+---------+-----------+-------------+
10 rows in set (0.00 sec)

Jetzt ist Marys Nachname Rantherpeen und sie ist 62 Jahre alt. Wenn man in Betracht zieht, dass sie zuvor 22 war, wird sie von meinen Änderungen nicht sehr begeistert sein.

Daten löschen

Weil Sie die Suchausdrücke bereits kennen gelernt haben, sollte der delete-Befehl kein Problem für Sie darstellen. Viele der SQL-Befehle verwenden zur Auswahl von Datensätzen aus Datenbanktabellen dieselben Suchausdrücke.

Mit dem delete-Befehl löschen Sie einen ganzen Datensatz, nicht nur einzelne Felder daraus. Sie brauchen nur den Namen eines Feldes und einen Suchausdruck angeben, um die zu löschenden Datensätze auszuwählen.

delete from <tabellenname> [WHERE <suchausdruck>]

Ähnlich update kann delete ohne WHERE-Klausel und Suchausdruck ausgeführt werden. Wie Sie zuvor jedoch gesehen haben, werden damit alle Datensätze einer Tabelle ausgewählt. Wenn in dem delete-Befehl alle Datensätze ausgewählt werden, werden sie alle gelöscht! Seien Sie also vorsichtig bei der Definition Ihrer Suchausdrücke für das Löschen, sonst stellen Sie irgendwann fest, dass Sie unbeabsichtigt Datensätze gelöscht haben, die Sie niemals löschen wollten.

Es ist sinnvoll, den Suchausdruck vorab mithilfe eines select-Ausdrucks zu überprüfen, um sich davon zu überzeugen, was gelöscht wird, bevor das Löschen tatsächlich ausgeführt wird.

Damit haben Sie ausreichend viele Grundlagen, um mit Datenbankstrukturen und - Informationen zu arbeiten. Die eigentliche Leistungsstärke von SQL wurde damit noch nicht deutlich, aber dazu kommen wir gleich.

12.5 Datenbanktabellen abfragen

Nachdem Sie Informationen in Ihren Datenbanktabellen abgelegt haben, werden Sie lernen, diese Daten abzufragen - und hier kommt die eigentliche Leistungsstärke von SQL zu Tage.

SQL-Datenbanken sind relational. Das bedeutet, Sie können mehrere Tabellen anlegen und die darin enthaltenen Informationen verknüpfen. In den Beispieldateien hat jeder Angestellte eine Titel-ID (titleID), mit deren Hilfe den Angestellten Jobnamen zugeordnet werden.

Durch die Kombination von Informationen aus unterschiedlichen Tabellen kann man wirklich leistungsfähige Abfragen formulieren, die in einfachen Datenbanksystemen mit flacher Dateistruktur nicht möglich wären.

Alle Abfragen verwenden den select-Befehl, um Datensätze aus einer Tabelle oder - abhängig vom Suchausdruck - auch aus mehreren Tabellen auszuwählen. Ein vereinfachtes Modell der select-Syntax sieht wie folgt aus:

select <feldname1>,<feldname2>,... 
from <tabellenname 1>,<tabellenname 2>,...
[where <suchausdruck>] [ORDER BY <ausdruck> ASC|DESC]

Wenn Sie alle Felder in einer oder mehreren Tabellen auswählen wollen, brauchen Sie nicht alle Felder aufzulisten. Statt dessen geben Sie als Abkürzung für alle Felder den Stern an, *.

Die einfachste Abfrage (die Sie bereits kennen gelernt haben) wählt alle Datensätze aus einer einzelnen Tabelle aus:

select * from <tabellenname>
mysql> select * from tbljobtitle;

+---------+---------------+----------+----------+
| titleID | description | lowersal | uppersal |
+---------+---------------+----------+----------+
| 1 | President/CEO | 100000 | 250000 |
| 2 | Manager | 10000 | 25000 |
| 3 | Programmer | 300000 | 350000 |
| 4 | Designer | 1000 | 5000 |
+---------+---------------+----------+----------+
4 rows in set (0.01 sec)

Versuchen Sie, alle Datensätze aus allen Tabellen auszuwählen (select * from tblemployee,tbljobtitle); das Ergebnis ist interessant. Statt eine Tabelle nach der anderen anzuzeigen, wird eine Kombination aus beiden Tabellen ausgegeben (das so genannte kartesische Produkt) - jedem Datensatz aus tblemployee wird ein Datensatz aus tbljobtitle zugeordnet.

Informationen sortieren

Um Informationen aus der Basis eines der Felder zu sortieren, verwenden Sie order by in Kombination mit einem Ausdruck (häufig ein oder mehrere durch Kommas voneinander getrennte Feldnamen) und asc für aufsteigende oder desc für absteigende Reihenfolge:

mysql> select * from tbljobtitle order by uppersal desc;
+---------+---------------+----------+----------+
| titleID | description | lowersal | uppersal |
+---------+---------------+----------+----------+
| 3 | Programmer | 300000 | 350000 |
| 1 | President/CEO | 100000 | 250000 |
| 2 | Manager | 10000 | 25000 |
| 4 | Designer | 1000 | 5000 |
+---------+---------------+----------+----------+
4 rows in set (0.00 sec)

Diese Abfrage ist gut geeignet, um alle Informationen aus einer bestimmten Tabelle zu ermitteln, aber das ist nicht besonders aufregend. Um SQL wirklich sinnvoll einzusetzen, müssen wir Abfragen formulieren, die Daten aus verschiedenen Tabellen kombinieren.

Tabellen verknüpfen

Um die Funktionsweise einer komplexen Abfrage zu beobachten, müssen wir Informationen aus mehreren Tabellen verknüpfen. Das bedeutet, dass wir eine Beziehung zwischen den verschiedenen Tabellen einrichten und die Informationen auf sinnvolle Weise kombinieren.

Angenommen, wir wollen eine Liste mit den Namen der verschiedenen Angestellten und ihrem Jobtitel anzeigen. Weil der Jobtitel in einer anderen Tabelle als die restlichen Informationen abgelegt ist, müssen wir die Tabellen verknüpfen. Wir verwenden dazu das Feld titelid, das in beiden Tabellen vorhanden ist, und formulieren damit eine Abfrage, die genau macht, was wir wünschen:

select firstname,lastname,description from tblemployee,tbljobtitle WHERE 
tblemployee.titleid=tbljobtitle.titleid;
mysql> select firstname,lastname,description from tblemployee,tbljobtitle WHERE
tblemployee.titleid=tbljobtitle.titleid;

+-----------+-------------+---------------+
| firstname | lastname | description |
+-----------+-------------+---------------+
| Steve | Jobs | President/CEO |
| Maddy | Dogg | Manager |
| Mary | Rantherpeen | Manager |
| John | Ray | Programmer |
| Klaus | Meine | Programmer |
| Robyn | Ness | Programmer |
| Anne | Groves | Programmer |
| Peter | Paul | Designer |
| Herman | Rarebell | Designer |
| Julie | Vujevich | Designer |
+-----------+-------------+---------------+
10 rows in set (0.00 sec)

In diesem Beispiel sehen Sie, dass es zwei Möglichkeiten gibt, auf Felder zuzugreifen: im erweiterten Format als <tabellenname>.<feldname>, oder einfach über den Feldnamen.

Falls Sie mehrere Tabellen kombinieren, die denselben Feldnamen enthalten, müssen Sie dieses Format verwenden, um sicherzustellen, dass der SQL-Server die Felder korrekt zuordnen kann. Sie sollten sich diese Schreibweise für Ihre Abfragen angewöhnen, sodass Sie nie in eine Situation geraten, wo die Struktur Ihrer Tabellen die Konsistenz Ihrer Abfragen zerstört.

In dieser Abfrage wird die Beziehung zwischen den Tabellen definiert als

WHERE tblemployee.titleid=tbljobtitle.titleid

Der Suchausdruck ist jedoch nicht auf eine einzige Beziehung begrenzt - er kann beliebig viele der anderen Ausdrücke enthalten, die wir heute vorgestellt haben. Wie wäre es beispielsweise mit einer Abfrage, die alle Datensätze auswählt, in denen das Gehalt (salary) größer 25000$ ist?

Versuchen Sie das Folgende:

select firstname,lastname,description from tblemployee,tbljobtitle WHERE
tblemployee.titleid=tbljobtitle.titleid AND tblemployee.salary>25000.00;
mysql> select firstname,lastname,description from tblemployee,tbljobtitle WHERE
tblemployee.titleid=tbljobtitle.titleid AND tblemployee.salary>25000.00;

+-----------+----------+---------------+
| firstname | lastname | description |
+-----------+----------+---------------+
| Steve | Jobs | President/CEO |
| John | Ray | Programmer |
| Klaus | Meine | Programmer |
| Robyn | Ness | Programmer |
| Anne | Groves | Programmer |
+-----------+----------+---------------+
5 rows in set (0.01 sec)

Es funktioniert, aber die Gehälter werden nicht angezeigt. Dies liegt am Entwurf - und war beabsichtigt, um Ihnen zu zeigen, dass eine Abfrage vielleicht nur ein paar Felder zurückgibt, der eigentliche Suchausdruck aber keinen Zugriff auf die Feldinformation hat.

Wir wollen irgendwohin - aber wir wollen dort nicht enden. Wir versuchen, alle Angestellten zu finden, die mindestens 75 % der Gehaltsobergrenze erreichen, d.h. tblemployee .salary>=(.75*tbljobtitle.uppersal).

mysql> select firstname,lastname,salary,uppersal 
from tblemployee,tbljobtitle
WHERE tblemployee.titleid=tbljobtitle.titleid
AND tblemployee.salary>=(.75*tbljobtitle.uppersal);

+-----------+----------+---------+----------+
| firstname | lastname | salary | uppersal |
+-----------+----------+---------+----------+
| Maddy | Dogg | 24000.8 | 25000 |
| John | Ray | 300001 | 350000 |
| Anne | Groves | 300001 | 350000 |
+-----------+----------+---------+----------+
3 rows in set (0.00 sec)

Wie Sie sehen, ist es ganz einfach, in einer Abfrage ein bisschen Mathematik einzusetzen, um mehr als nur einen Vergleich auf Gleichheit auszuführen.

Berechnungen in einer Abfrage

Das letzte Beispiel hat gezeigt, wie man einen mathematischen Ausdruck in eine Abfrage aufnimmt, aber damit haben wir noch keine Möglichkeit, wirklich anzuzeigen, wie das Ergebnis der Berechnung aussieht. Wenn wir mit 75 % einer Gehaltsobergrenze vergleichen, wäre es ganz praktisch zu wissen, wie viel 75 % sind.

Wir können die Abfrage leicht abwandeln, indem wir eine SQL-Variable einführen, die das Berechnungsergebnis zurückgibt, so als handelte es sich dabei um ein Feld in der Datenbank. Dieses virtuelle Feld hat das folgende Format:

<ausdruck> as '<variablenname>'

Angenommen, wir wollen jetzt den Prozentsatz der Gehaltsobergrenze anzeigen, den die einzelnen Angestellten erhalten. Die Berechnung ist ganz einfach:

((tblemployee.salary/tbljobtitle.uppersal)*100)

Um dies mit den restlichen Informationen über die Angestellten in einer Tabelle anzuzeigen, könnten Sie die folgende Abfrage formulieren:

select firstname,lastname,salary,uppersal,
round((tblemployee.salary/tbljobtitle.uppersal)*100)
as 'percent' from tblemployee,tbljobtitle
WHERE tblemployee.titleid=tbljobtitle.titleid;

Beachten Sie, dass ich auch die Funktion round verwendet habe, die für die Gehaltsberechnung eingesetzt wird. Diese Funktion rundet das Ergebnis der Berechnung auf eine ganze Zahl. Sie müssen diese Funktion nicht verwenden, aber sie macht die Ergebnisse viel lesbarer.

mysql> select firstname,lastname,salary,uppersal,
round((tblemployee.salary/tbljobtitle.uppersal)*100)
as 'percent' from tblemployee,tbljobtitle
WHERE tblemployee.titleid=tbljobtitle.titleid;

+-----------+-------------+---------+----------+---------+
| firstname | lastname | salary | uppersal | percent |
+-----------+-------------+---------+----------+---------+
| Steve | Jobs | 128313 | 250000 | 51 |
| Maddy | Dogg | 24000.8 | 25000 | 96 |
| Mary | Rantherpeen | 10812.9 | 25000 | 43 |
| John | Ray | 300001 | 350000 | 86 |
| Klaus | Meine | 150321 | 350000 | 43 |
| Robyn | Ness | 200001 | 350000 | 57 |
| Anne | Groves | 300001 | 350000 | 86 |
| Peter | Paul | 1105.25 | 5000 | 22 |
| Herman | Rarebell | 1000 | 5000 | 20 |
| Julie | Vujevich | 2435.12 | 5000 | 49 |
+-----------+-------------+---------+----------+---------+
10 rows in set (0.01 sec)

Damit haben Sie plötzlich direkt in einer Abfrage Zugriff auf Daten, die zuvor überhaupt nicht existierten! In UltraDev enthält die von dieser Abfrage erzeugte Datensatzgruppe ein Prozentfeld, das nicht einmal in den eigentlichen Datentabellen enthalten ist.

Werkzeuge zur Summenbildung

Auch die Summenbildung ist in Abfragen sehr sinnvoll. Mithilfe von Funktionen zur Summenbildung ermitteln Sie ganz einfach Gesamtsummen für numerische Spalten oder zählen die Anzahl der Datensätze eines bestimmten Typs. Einige dieser Funktionen werden wir hier betrachten:

max() - Der Maximalwert in einem bestimmten Feld. Wird verwendet, um den höchsten Wert zu ermitteln. Wenn Sie max beispielsweise auf ein Gehaltsfeld in der Angestellten- Tabelle anwenden, gibt es das höchste Gehalt in der Gruppe zurück.

mysql> select round(max(salary)) from tblemployee;
+--------------------+
| round(max(salary)) |
+--------------------+
| 300001 |
+--------------------+
1 row in set (0.02 sec)

In mehreren Beispielen, so auch in diesem, habe ich auf das Ergebnis die Funktion round angewendet, um eine übersichtlichere Antwort anzuzeigen.

min() - Ermittelt den Minimalwert in einem bestimmten Feld. Dies ist das Gegenteil der Funktion max.

mysql> select round(min(salary)) from tblemployee;
+--------------------+
| round(min(salary)) |
+--------------------+
| 1000 |
+--------------------+
1 row in set (0.02 sec)

sum() - Addiert die Werte eines bestimmten Feldes. Beispielsweise könnte diese Funktion verwendet werden, um die Gesamtsumme der gezahlten Gehälter zu ermitteln:

mysql> select round(sum(salary)) from tblemployee;
+--------------------+
| round(sum(salary)) |
+--------------------+
| 1117991 |
+--------------------+
1 row in set (0.01 sec)

count() - Zählt die Anzahl der Auftreten eines Wertes in einem bestimmten Feld.

mysql> select count(salary) from tblemployee;
+---------------+
| count(salary) |
+---------------+
| 10 |
+---------------+
1 row in set (0.03 sec)

Auf den ersten Blick erkennen Sie vielleicht nicht den Sinn dieser Funktionen. Schließlich handelt es sich dabei nur um einen Zähler für die Datensätze, die von einer Abfrage zurückgegeben werden, und UltraDev stellt diese Zahl auch bereit, ohne dass Sie dafür eine separate Abfrage ausführen müssen.

Sie können diese Summierungswerkzeuge jedoch mit der Funktion group by kombinieren, um Daten in Gruppen einzuteilen und dafür Summen zu bilden. Angenommen, wir wollen eine Liste erstellen, die Auskunft darüber gibt, wie viele Leute innerhalb der einzelnen Jobklassifikationen arbeiten. Zunächst würden Sie dafür vielleicht eine Abfrage wie die folgende erstellen:

select description,count(tblemployee.titleID) 
as 'total_employed' from tbljobtitle,tblemployee
where tbljobtitle.titleID=tblemployee.titleID

Wir hoffen, dass die beiden Tabellen damit verknüpft werden und auch die Spalte total_employed bereitgestellt wird, die auf dem Zähler (count) des Feldes titleID in der Tabelle tblemployee basiert.

Leider hat der Datenbankserver keine Möglichkeit zu erkennen, wie er die verschiedenen Datensätze gruppieren kann, um sie zu zählen - also wird die Abfrage fehlschlagen. In MySQL erhalten Sie dafür eine Antwort wie beispielsweise

ERROR 1140: Mixing of GROUP columns (MIN(),MAX(),COUNT()...) with no GROUP columns is illegal if there is no GROUP BY clause

Um dies zu vermeiden, müssen Sie eine group by-Klausel in die Abfrage einführen, die die zu gruppierenden Felder auflistet - in diesem Fall tblemployee.titleID.

mysql> select description,count(tblemployee.titleID) 
as 'total_employed' from tbljobtitle,tblemployee
where tbljobtitle.titleID=tblemployee.titleID group by (tbljobtitle.titleID);


+---------------+----------------+
| description | total_employed |
+---------------+----------------+
| President/CEO | 1 |
| Manager | 2 |
| Programmer | 4 |
| Designer | 3 |
+---------------+----------------+
4 rows in set (0.03 sec)

Daraus erhalten wir wie von Zauberhand eine Tabelle aller Jobbezeichnungen, gefolgt von der Anzahl der Angestellten innerhalb der einzelnen Klassifikationen.

12.6 Andere komplexe Techniken

Es gibt unzählige Bücher über SQL und seine Befehle. Diese Ausführlichkeit ist hier natürlich nicht möglich. Unser heutiges Ziel ist, Ihnen ausreichend viel Hintergrundwissen zu verschaffen, damit Sie Abfragen entwickeln und Ihrer Applikation eine komplexe Funktionalität zu geben, ohne Ihren eingebetteten Code manuell bearbeiten zu müssen.

Bevor Sie erfahren, wie sich all dies in die UltraDev-Umgebung eingliedert, wollen wir einen Blick auf die weiteren Wunder der SQL-Welt werfen, die Sie noch erwarten. Dies sind einige der Funktionen, an denen Sie interessiert sein könnten, die aber momentan von MySQL nicht unterstützt werden. Sie sind zwar praktisch, aber normalerweise gibt es Lösungen, die dieselbe Funktionalität realisieren, ohne dass man auf ein kommerzielles (und teures) Datenbanksystem umsteigen muss.

Ansichten

Wie bereits erwähnt, sind Ansichten im Wesentlichen virtuelle Tabellen, die auf Abfragen basieren. Nachdem eine Ansicht erstellt wurde, greifen Sie darauf wie auf eine Tabelle zu. Die Syntax zum Anlegen einer Ansicht ist einfach, aber Sie müssen dafür verstehen, wie man komplexe Abfragen entwickelt:

create view <ansichtname> [<feldname1>,<feldname2>,...] as <select-anweisung>

Die Feldnamen können angegeben werden, um neue Namen für bereits existierende Felder einzuführen. Werden sie weggelassen, übernimmt die Ansicht die Felder der existierenden Tabellen. Wie Sie später in diesem Buch noch sehen werden, hat UltraDev Probleme, auf identisch benannte Felder zuzugreifen, deshalb sollten Sie in diesem Fall auf Ansichten zurückgreifen, wenn Ihr Datenbanksystem diese unterstützt.

Wie Datenbanken und Tabellen löschen Sie auch Ansichten mit dem Befehl drop:

drop view <ansichtname>

Falls Sie an einem System interessiert sind, das Ansichten unterstützt, informieren Sie sich über PostgreSQL (http://www.pgsql.com/) oder eine kommerzielle Lösung wie beispielsweise Oracle oder SQL Server von Microsoft.

Gespeicherte Prozeduren

Gespeicherte Prozeduren ermöglichen Ihnen, Applikationslogik direkt innerhalb Ihres Datenbankservers zu schreiben und sie als Abfragen auszuführen. Die Verwendung gespeicherter Prozeduren weist Vor- und Nachteile auf, und überraschenderweise sind sie austauschbar.

Die meisten Datenbankserver ermöglichen Ihnen, mithilfe von SQL oder einer anderen Sprache gespeicherte Prozeduren zu schreiben. SQL eignet sich nicht zur Programmierung und kann nur genutzt werden, um Funktionen auszuführen, die auch in einer Abfrage ausgeführt werden können. Die eigentliche Leistung entsteht also dadurch, dass man die Prozeduren in der dem Datenbankserver eigenen Sprache schreibt. Weil diese Sprachen im Allgemeinen serverspezifisch sind, sind sie jedoch leider nicht unbedingt auf andere Systeme übertragbar. Ihr Code kann damit nur auf der SQL- Serverplattform ausgeführt werden, auf der er entwickelt wurde.

Der Vorteil gespeicherter Prozeduren ist, dass es damit größtenteils überflüssig wird, benutzerdefinierten eingebetteten Code auf Ihren Webseiten bereitzustellen, um die Applikationslogik zu verarbeiten. Das bedeutet, wenn Sie Ihre Web-Applikation unter Verwendung gespeicherter Prozeduren entwickeln, können Sie sie auf jeder Server- Plattform (ASP, JSP usw.) unter Verwendung derselben Programmiertechniken ausführen, solange Sie dieselbe SQL-Serverplattform verwenden.

Wie Sie sehen, können gespeicherte Prozeduren die Plattformabhängigkeit sowohl erhöhen als auch verringern. Welche Abhängigkeiten die wichtigeren sind, bleibt völlig Ihnen überlassen. In diesem Buch habe ich bei Bedarf den eingebetteten Servercode abgeändert - andernfalls hätte dieses Buch auch Datenbanksprachen zum Thema haben müssen.

Ein sinnvoller Verwendungszweck gespeicherter Prozeduren ist die Verarbeitung sicherer Informationen. Bei der Implementierung von Routinen, für die ein sicherer Zugriff erforderlich ist, hält man die Applikationslogik am besten vom Webbrowser getrennt. Statt beispielsweise die Information für die Kreditkartenverarbeitung in ein Active-X-Steuerelement auf Ihrer Webseite einzubetten, ist es viel besser, sie durch eine gespeicherte Prozedur in einer Datenbank verarbeiten zu lassen.

Unterabfragen

Eine interessante Funktion von SQL (auf einigen Servern, nicht jedoch in MySQL) ist die Möglichkeit, select-Anweisungen in andere Anweisungen einzubetten.

Beispielsweise haben Sie bereits gesehen, wie man das geringste Gehalt aus der Angestellten-Tabelle ermittelt:

mysql> select min(salary) from tblemployee;
+--------------------+
| min(salary) |
+--------------------+
| 1000 |
+--------------------+
1 row in set (0.02 sec)

Nachdem Sie dieses geringste Gehalt ermittelt haben, sind Sie leider immer noch eine Abfrage davon entfernt, wer der arme Kerl ist:

select * from tblemployee where salary='1000';

Mithilfe einer Unterabfrage formulieren Sie die Abfragen neu:

select * from tblemployee where salary=(select min(salary) from tblemployee);

Die innere Abfrage wird als Erstes ausgeführt und in der übergeordneten Abfrage verwendet. Sie können die Abfragen über mehrere Ebenen einbetten, die jeweils Ergebnisse an die ihnen übergeordneten Ebenen zurückgeben.

Die Komplexität dieser Abfragen bleibt völlig Ihnen überlassen. Unterabfragen sind mit Joins zu vergleichen, bieten aber die Möglichkeit, in einem Schritt zu erledigen, wofür andernfalls mehrere Schritte erforderlich wären.

12.7 Komplexe Abfragen und UltraDev

Was genau sind komplexe Abfragen und wie führt man sie in UltraDev aus? Die Antwort auf die erste Frage ist einfach - alles, woran mehr als eine Tabelle beteiligt ist, ist in UltraDev eine komplexe Abfrage. Der einfache Abfragedialog erlaubt nur die Anzeige aus den Feldern einer einzigen Tabelle.

Die Oberfläche für die Eingabe einer komplexen Abfrage ist einfach. Und hier werden Sie es vermutlich bequemer finden, das SQL manuell einzugeben, statt durch Zeigen und Klicken.

Öffnen Sie UltraDev und eine Verbindung zu einer aktiven Datenbank, und fügen Sie dann Ihrem Dokument eine Datensatzgruppe hinzu:

  1. Öffnen Sie die Palette Serververhalten.
  2. Klicken Sie auf das Plussymbol (+) und wählen Sie Datensatzgruppe (Abfrage).
  3. Klicken Sie auf die Schaltfläche Erweitert, um den Dialog für die erweiterte Abfragekonfiguration anzuzeigen.

Abbildung 12.2 zeigt den Dialog für die erweiterte Abfragekonfiguration.

Abbildung 12.2:  Erweiterte Abfragen sind in UltraDev definiert als alles, wofür mehrere Tabellen oder spezielle Datenbankfunktionen benötigt  werden.

Wenn Sie sich Schreibarbeit ersparen wollen, können Sie der Datenbankabfrage im Bereich Datenbankelemente Objekte hinzufügen.

Es gibt drei Komponenten, mit denen Sie arbeiten können:

Jede davon kann erweitert werden, indem Sie links auf das Pluszeichen klicken, um die darunter abgelegten Elemente anzuzeigen. Beispielsweise enthalten die Kategorien Tabellen und Ansichten alle Tabellen und Ansichten der aktuellen Verbindung. Gespeicherte Prozeduren enthalten alle verfügbaren gespeicherten Prozeduren.

Jede dieser Kategorien kann geöffnet werden, um zusätzliche Datenbankinformationen anzuzeigen, wie beispielsweise einzelne Felder.

Um diese Elemente in eine Abfrage aufzunehmen, verwenden Sie die drei Schaltflächen rechts im Bereich Datenbankelemente. Durch Drücken einer dieser Schaltflächen fügen die Elemente das entsprechende SQL in das Abfragefenster ein, wenn die geeigneten Daten in der Datenbank ausgewählt sind.

Jede der Schaltflächen kann für einen bestimmten Typ von Datenbankelementen verwendet werden:

Wie Sie sehen, ist das nicht gerade das Niveau der Weltraumforschung. Der Abfrage-Editor ist auf die Entwicklung einer grundlegenden SQL-Abfrage beschränkt, die Sie manuell einrichten müssen. Wie ich bereits erwähnt habe, halte ich es für einfacher, das SQL direkt in die Applikation einzugeben, statt sich innerhalb der Anzeige mit den Datenbankelementen und den Schaltflächen SELECT, WHERE und ORDER BY einen Weg zu klicken.

12.8 Zusammenfassung

In diesem Kapitel haben Sie erfahren, wie man Datenbanken, Tabellen und Abfragen in SQL einrichtet und wie man sie direkt in UltraDev eingibt, um ein sehr viel leistungsfähigeres System zu gestalten, als es mit den einfachen Abfragen möglich ist.

SQL ist eine sehr flexible Sprache für relationale Datenbanken, die erlaubt, mit Daten so zu arbeiten, wie es in anderen Systemen nicht möglich ist. Die grundlegende Syntax ist extrem einfach zu verstehen und erlaubt sogar dem erfahrensten Programmierer, komplexe relationale Systeme zu entwickeln.

MySQL bietet keine Unterstützung einiger der komplexeren Funktionsmerkmale von SQL, aber es ist ausreichend funktional für viele kleine bis mittelgroße Websites. Alle Projekte in diesem Buch wurden mit MySQL implementiert. Weitere Informationen über MySQL finden Sie auch in Anhang C im Schnellüberblick über die Funktionen.

12.9 Fragen und Antworten

Frage:
Wird MySQL irgendwann Ansichten und Unterabfragen unterstützen?

Antwort:
Vielleicht. Beide Funktionen befinden sich auf der Wunschliste für die Software.

Frage:
Wie kann ich in SQL Datumswerte vergleichen?

Antwort:
Sie verwenden dazu dieselben Vergleichsoperatoren wie für andere Datentypen (=, <, > usw.). Der SQL-Server übernimmt die eigentliche Arbeit für Sie.

Frage:
Können mehr als zwei Tabellen verknüpft werden?

Antwort:
Natürlich. Ich habe die Beispiele auf eine einzige Tabellenverknüpfung beschränkt, weil nur beschränkt viel Platz zur Verfügung stand. Sie können in SQL auch ganz einfach drei, vier oder mehr Tabellen verknüpfen.

Frage:
Kann ich Daten in einer Ansicht aktualisieren?

Antwort:
Das ist von den Funktionsmerkmalen Ihres Datenbankservers abhängig. Viele Server bieten die Möglichkeit, die Daten aus Ansichten zu aktualisiere und weisen diese Aktualisierungen sogar zurück, wenn die aktualisierten Daten nicht mehr in der Ansicht enthalten sind.

12.10 Workshop

Der Workshop dient dazu, den gelesenen Stoff mithilfe von gezielten Fragen und Übungen zu vertiefen. Die Antworten finden Sie in Anhang A, »Quiz-Antworten«.

Quiz

  1. Wie legen Sie in SQL eine Datenbank an?
  2. Warum ist der Satz »Daten in die Datenbank einfügen« syntaktisch falsch?
  3. Was bedeutet das Zeichen * in einer select-Anweisung?
  4. Wie verweisen Sie auf einen bestimmten Feldnamen in einer bestimmten Tabelle?
  5. Was passiert, wenn Sie bei der Auswahl von Datensätzen keine WHERE-Klausel angeben?

Übung

Weil dieses Kapitel versucht hat, Ihnen die Flexibilität und die Leistungsstärke von SQL zu demonstrieren, sollten Sie hier nur ein paar der heute vorgestellten Techniken ausprobieren. Versuchen Sie, eine eigenen Filmdatenbank anzulegen, indem Sie die folgenden Tabellen einrichten:

film - Filmtitel, Jahr usw.

filmtyp - Kategorien (Horror, Thriller, Komödie usw.)

schauspieler - Schauspieler in den Filmen, die Sie auf Video oder DVD haben

Das Schwierigste beim Aufbau dieser Datenbankstruktur (und der unterstützenden Abfragen) ist die Verknüpfung der Schauspielertabelle (actor) mit der Filmtabelle (movie). In Kapitel 6, »Einführung in dynamische Webanwendungen und Datenbankentwicklung«, finden Sie weitere Informationen zur Normalisierung. Hinweis: Sie brauchen eine zweite Tabelle, um eine Film-ID und eine Schauspieler-ID zu verknüpfen.



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbackKapitelanfangnächstes Kapitel


© Markt+Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH