SQL (das Kürzel für Structured Query Language; offizielle Aussprache [ɛskjuːˈɛl], häufig auch [ˈsiːkwəl] →SEQUEL), ist eine Datenbanksprache zur Definition, Abfrage und Manipulation von Daten in relationalen Datenbanken. SQL ist von ANSI und ISO standardisiert und wird von fast allen gängigen Datenbanksystemen unterstützt. SQL umfasst die folgenden Datenbanksprachen: Data Manipulation Language, Data Definition Language, Data Control Language.
Die Syntax von SQL ist relativ einfach aufgebaut und semantisch an die englische Umgangssprache angelehnt. SQL stellt eine Reihe von Befehlen zur Definition von Datenstrukturen nach der relationalen Algebra, zur Manipulation von Datenbeständen (Einfügen, Bearbeiten und Löschen von Datensätzen) und zur Abfrage von Daten zur Verfügung. Durch seine Rolle als Quasi-Standard ist SQL von großer Bedeutung, da eine weitgehende Unabhängigkeit von der benutzten Software erzielt werden kann.
Die meisten heute verbreiteten Datenbanksysteme implementieren Teile des SQL-Sprachstandards. Dadurch ist es möglich, Anwendungsprogramme zu erstellen, die vom verwendeten Datenbanksystem unabhängig sind. In der Vor-SQL-Zeit gelang dies mit dem System der kompatiblen Schnittstellen. Viele SQL-Implementierungen bieten darüber hinaus allerdings noch herstellerspezifische Erweiterungen, die nicht dem Standard-Sprachumfang entsprechen, was zur Folge hat, dass von den Herstellern parallel entwickelte gleiche Funktionen unterschiedliche Sprachelemente benutzen.
1986 wurde der erste SQL-Standard vom ANSI verabschiedet (welcher dann 1987 von der ISO ratifiziert wurde). 1992 wurde der Standard deutlich überarbeitet und als SQL-92 (oder auch SQL2) veröffentlicht. Alle aktuellen Datenbanksysteme halten sich im wesentlichen an diese Standardversion. Die Version SQL:1999 (ISO/IEC 9075:1999, auch SQL3 genannt) ist noch nicht in allen Datenbanksystemen implementiert. Das gilt auch für die nächste Version SQL:2003. Der aktuelle Standard wurde 2008 unter SQL:2008 verabschiedet.
Inhaltsverzeichnis |
SQL-Befehle lassen sich in drei Kategorien unterteilen (Zuordnung nach der Theorie der Datenbanksprachen in Klammern):
Im weiteren Verlauf des Abschnitts werden viele SQL-Befehle erklärt; Grundlage ist dabei das folgende Beispiel:
| ERD: | ||||||||||||||||||||||||||||||||||||||||||||||
![]() |
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| Relationen: | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|||||||||||||||||||||||||||||||||||||||||||
Die SELECT-Anweisung startet eine Abfrage. Aufgrund der Syntax kann eine SELECT-Anweisung auch als „SFW-Block“ (SELECT, FROM, WHERE) bezeichnet werden. Syntax (unvollständig):
SELECT [DISTINCT] Auswahlliste FROM Quelle [WHERE Where-Klausel] [GROUP BY (Group-by-Attribut)+ [HAVING Having-Klausel]] [ORDER BY (Sortierungsattribut [ASC|DESC])+];
* für alle) und ob Aggregatfunktionen anzuwenden sind. Wie bei allen anderen Aufzählungen werden die einzelnen Elemente mit Komma voneinander getrennt.Mengenoperatoren können auf mehrere SFW-Blöcke angewandt werden, die gleich viele Attribute haben und bei denen die Datentypen der Attribute übereinstimmen:
Beispiele:
SELECT * FROM Student
SELECT MatrNr FROM Student
SELECT DISTINCT PersNr FROM Professor
SELECT MatrNr AS Matrikelnummer, Name FROM Student
SELECT VorlNr, Titel FROM Vorlesung WHERE PersNr = 12
SELECT a.VorlNr, a.Titel, b.PersNr, b.Name FROM Professor b, Vorlesung a WHERE b.PersNr = a.PersNr
SELECT a.VorlNr, a.Titel, b.PersNr, b.Name FROM Professor b INNER JOIN Vorlesung a ON b.PersNr = a.PersNr
SELECT a.VorlNr, a.Titel, b.PersNr, b.Name FROM Professor b LEFT OUTER JOIN Vorlesung a ON b.PersNr = a.PersNr
SELECT b.PersNr, b.Name FROM Professor b LEFT OUTER JOIN Vorlesung a ON b.PersNr = a.PersNr WHERE a.PersNr IS NULL
SELECT a.PersNr, a.Name FROM Professor a WHERE NOT EXISTS (SELECT * FROM Vorlesung WHERE PersNr = a.PersNr)
SELECT COUNT(b.PersNr) AS Anzahl, a.PersNr, a.Name FROM Professor a LEFT OUTER JOIN Vorlesung b ON a.PersNr = b.PersNr GROUP BY a.Name, a.PersNr
Syntax (unvollständig):
INSERT INTO Relation [( Attribut+ )] VALUES ( ( Konstante+ ) )+ INSERT INTO Relation [( Attribut+ )] SFW-Block UPDATE Relation SET (Attribut=Ausdruck)+ [WHERE Where-Klausel] DELETE FROM Relation [WHERE Where-Klausel]
UPDATE Personal SET Gehalt=Gehalt*2 WHERE Abteilung='EDV'
Beispiele:
INSERT INTO Student (MatrNr,Name) VALUES (27123, 'Meier')
INSERT INTO Student (MatrNr,Name) VALUES (27124, 'Schulz'), (27125, 'Schmidt')
INSERT INTO Student VALUES (27126, 'Schmidt')
INSERT INTO Student (MatrNr,Name) SELECT MatrNr, Name FROM Student_alt
UPDATE Student SET Name='Meier' WHERE MatrNr = 27124
DELETE FROM Student
DELETE FROM Student WHERE MatrNr = 27124
Syntax (primary key und foreign key sind Teil der SQL-89 IDL bzw. SQL-92 und werden von manchen Datenbanksystemen nicht unterstützt):
CREATE TABLE Relation ( Attribut-Definition+ )
CREATE TABLE Relation ( (Attribut-Definition [PRIMARY KEY])+
[, FOREIGN KEY ( Attribut+ ) REFERENCES Relation ( Attribut+ )] )
DROP TABLE Relation
ALTER TABLE Relation Alter-Definition
CREATE INDEX Index-Name ON Relation ( Attribut+ )
DROP INDEX Index-Name
CREATE VIEW Sicht [( Attribut+ )] AS SFW-Block [WITH CHECK OPTION]
DROP VIEW Sicht
ADD Attribut-Definition. In SQL-92 gibt es noch ALTER Attribut Default-Wert oder DROP Attribut. Da SQL-92 sehr restriktiv bezüglich der ALTER-Anweisung ist, ist dies eine der Anweisungen, die von den Herstellern universell erweitert wurde, so dass beliebige Änderungen möglich sind wie durch eine Folge von DROP und ADD-Anweisungen.CREATE INDEX und DROP INDEX Anweisungen immer produktspezifische Erweiterungen sind. Allerdings verwenden die meisten DBMS die gleiche oder eine sehr ähnliche Syntax.Beispiele:
CREATE TABLE Student ( MatrNr INT NOT NULL PRIMARY KEY, Name varchar(50) NOT NULL)
ALTER TABLE Student ADD Vorname varchar(35)
DROP TABLE Student
CREATE INDEX idx_Name ON Student (Name)
DROP INDEX idx_Name
Diese Befehle regeln die Zugriffsrechte auf Datenbankobjekte. Syntax:
GRANT Operation+ ON Relation TO (PUBLIC|Benutzer) [WITH GRANT OPTION] REVOKE Operation+ ON Relation FROM (PUBLIC|Benutzer)
Beispiele:
GRANT SELECT, UPDATE ON TABLE Student TO groupx;
REVOKE EXECUTE ON PROCEDURE DSN8ED6 FROM PUBLIC;
In den oben vorgestellten Befehlen create table und alter table wird bei der Definition jeder Spalte angegeben, welchen Datentyp die Werte dieser Spalte annehmen können. Dazu liefert SQL eine ganze Reihe standardisierter Datentypen mit. Die einzelnen DBMS-Hersteller haben diese Liste jedoch um eine Unzahl weiterer Datentypen erweitert. Die wichtigsten Standarddatentypen sind:
smallint
int oder integer
bigint
numeric (n, m) oder decimal (n, m)
n Stellen, davon m nach dem Komma. Wegen der hier erfolgenden Speicherung als Dezimalzahl ist eine besonders für Geldbeträge notwendige Genauigkeit gegeben.float (m)
m Stellen nach dem Kommareal
double oder double precision
float und double sind für technisch-wissenschaftliche Werte geeignet und umfassen auch die Exponentialdarstellung. Wegen der Speicherung im Binärformat sind sie aber für Geldbeträge nicht geeignet, weil sich beispielsweise der Wert 0,10€ (entspricht 10 Cent) nicht exakt abbilden lässt.
character (n) oder char (n)
n druckbaren und/oder nicht druckbaren Zeichenvarchar (n) oder character varying (n)
n druckbaren und/oder nicht druckbaren Zeichen. Die Variante varchar2 ist für Oracle spezifisch, ohne dass sie sich tatsächlich unterscheidet.date
time
timestamp
boolean
true (wahr) oder false (falsch) annehmen). Dieser Datentyp ist laut SQL:2003 optional und nicht alle DBMS stellen diesen Datentyp bereit.blob (n) oder binary large object (n)
n Bytes Länge.clob (n) oder character large object (n)
n Zeichen Länge.Unabhängig vom Datentyp können alle Attribute auch den Wert NULL annehmen, wenn kein Wert bekannt ist oder aus anderen Gründen kein Wert gespeichert werden soll. Der NULL-Wert ist von allen anderen möglichen Werten des Datentyps verschieden.
Die folgenden Fachbegriffe sind zum Verständnis von SQL hilfreich. Sie sind jedoch auch als eigenständige Begriffe der Informatik bedeutsam und werden nicht nur im Kontext von SQL verwendet.
Über einen Schlüssel kann jedes Tupel innerhalb der Tabelle eindeutig identifiziert werden. Ein Schlüssel kann auch aus mehreren Attributen (Spalten) der Tabelle bestehen (zusammengesetzter Schlüssel). Ein Schlüssel ist entweder ein Primärschlüssel oder ein Schlüsselkandidat (manchmal auch als Sekundärschlüssel bezeichnet).
Der Primärschlüssel muss aus einem Merkmal oder einer minimalen Merkmalskombination (bei zusammengesetzten Primärschlüsseln) bestehen. Die Bedingung der minimalen Merkmalskombination bei zusammengesetzten Primärschlüsseln bedeutet, dass ein Teil (Merkmal) des zusammengesetzten Schlüssels nicht reichen darf, um jedes Tupel eindeutig zu identifizieren. Diese Bedingung kann und wird von existierenden Datenbanksystemen nicht erzwungen.
In jeder Tabelle sollte grundsätzlich ein Primärschlüssel (primary key) definiert werden. Dieser ist häufig der natürliche Schlüssel der Tabelle, wenn er eindeutig („unique“) ist; es kann auch ein künstlicher Schlüssel sein, beispielsweise ein Surrogatschlüssel, der pro Tupel hoch gezählt wird. Schlüsselkandidaten, d. h. weitere, unabhängige Schlüssel neben dem Primärschlüssel, können (und sollten) als Unique Constraints definiert werden.
Fremdschlüssel (auch Foreign Key genannt) bezeichnen im Bereich der relationalen Datenbanken ein Attribut einer Relation (Tabelle), das auf den Primärschlüssel oder einen Unique Key einer anderen (oder auch der gleichen) Relation verweist. Ein Fremdschlüssel kann, muss aber nicht Bestandteil des Primärschlüssel seiner Relation sein.
Eine Transaktion bezeichnet eine Menge von Datenbankänderungen die zusammen ausgeführt werden (müssen). So ist beispielsweise die Buchung (als Transaktion) eines Geldbetrags durch zwei atomare Datenbankoperationen „Abbuchen des Geldbetrages von Konto A“ und „Buchung des Geldbetrages auf Konto B“ gekennzeichnet. Kann die vollständige Abarbeitung der elementaren Datenbankoperationen der Transaktion nicht durchgeführt werden (z. B. aufgrund eines Fehlers) müssen alle durchgeführten Änderungen an dem Datenbestand auf den Ausgangszustand zurückgesetzt werden. Der Vorgang der alle Änderungen einer Transaktion zurücksetzt wird als Rollback bezeichnet. Der Begriff Commit bezeichnet das Ausführen einer Transaktion. Transaktionen sind eine Möglichkeit die Konsistenz des Datenbestandes zu sichern. Im Beispiel der doppelten Kontenführung wird durch das Verhindern von ungültigen Teilbuchungen eine ausgeglichene Kontobilanz gewährleistet.
Datenbanken erlauben es zum Teil, bestimmte Befehle außerhalb einer Transaktion auszuführen. Darunter fällt insbesondere das Laden von Daten in Tabellen oder das Exportieren von Daten mittels Utilities. Manche DBMS erlauben das temporäre Abschalten der Transaktionslogik sowie einiger Kontrollen zur Erhöhung der Verarbeitungsgeschwindigkeit. Dies muss allerdings meist durch einen expliziten Befehl erzwungen werden, um ein versehentliches Ändern von Daten außerhalb einer Transaktion zu vermeiden. Solche Änderungen können, falls eine Datenbankwiederherstellung erforderlich ist, zu schweren Problemen oder gar Datenverlusten führen. Eine Transaktion beendet man erfolgreich mit der SQL-Anweisung Commit. Alle Änderungen der Transaktion werden persistent gemacht, und das DBMS stellt durch geeignete (interne) Mittel (z. B. Logging) sicher, dass diese Änderungen nicht verloren gehen. Mit dem Befehl Rollback wird eine Transaktion ebenfalls beendet, es werden jedoch alle Änderungen seit Beginn der Transaktion rückgängig gemacht. Das heißt, der Zustand des Systems (in Bezug auf die Änderungen der Transaktion) ist der gleiche wie vor der Transaktion.
Als Dateninkonsistenz wird allgemein die Widersprüchlichkeit von Daten bezeichnet. Diese besteht, wenn Daten bspw. die Integritätsbedingungen (z. B. Constraints oder Fremdschlüsselbeziehungen) nicht erfüllen. So können Referenzen einer Tabelle auf Records einer anderen verweisen. Wurde dieser referenzierte Eintrag aber bereits gelöscht, so sind die Daten in der ersten (referenzierenden) Tabelle inkonsistent, weil ein Verweis auf einen nicht vorhandenen Record referenziert.
Ursachen für Dateninkonsistenzen können Fehler bei der Analyse des Datenmodells, fehlende Normalisierung des ERM oder Fehler in der Programmierung sein.
Zum letzteren gehören die Lost-Update-Phänomene sowie die Verarbeitung von zwischenzeitlich veralteten Zwischenergebnissen. Dies tritt vor allem bei der Online-Verarbeitung auf, da dem Nutzer angezeigte Werte nicht in einer Transaktion gekapselt werden können.
Beispiel: Transaktion A liest Wert x Transaktion B verringert Wert x um 10 Transaktion A erhöht den gespeicherten Wert von x um eins und schreibt zurück Ergebnis x' = x+1 Die Änderung von B ist verloren gegangen
Von referentieller Integrität spricht man, wenn jeder Fremdschlüssel einer Tabelle einem entsprechenden Primärschlüssel einer anderen Tabelle zugeordnet, oder der Wert des Fremdschlüssels NULL ist. Die referentielle Integrität garantiert die Existenz des Schlüssels in der referenzierten Tabelle.
Um Dateninkonsistenzen zu vermeiden, können Beziehungen zwischen Tabellen definiert werden. Zusätzlich können Regeln angegeben werden, wie abhängige Daten beim Löschen oder Ändern eines Datensatzes behandelt werden sollen. Beim Löschen können zum Beispiel durch Kaskadierung ein Datensatz und mit ihm alle abhängigen Daten gelöscht werden.
Folgende Änderungsregeln sind möglich:
ON DELETE CASCADE werden ebenfalls alle abhängigen Datenzeilen gelöscht.Ein Update von Primärschlüsseln (PK-Update) ist zwar von Codd vorgesehen. Manche Datenbankadministratoren und Anwendungsentwickler sind jedoch der Ansicht, dass dies der grundsätzlichen Idee des Schlüssels widerspräche. Sie betrachten einen Primärschlüssel als stets unveränderlich. In solchen Fällen werden meist Surrogatschlüssel eingesetzt, da diese bei Änderung der Daten gleich bleiben können.
Ein Grundsatz des Datenbankdesigns ist, dass in einer Datenbank keine Redundanzen auftreten sollen. Man spricht dann von einer redundanzfreien Datenbank. Dies wird durch die Normalisierung erreicht.
In manchen Fällen ist die Performance einer Datenbank besser, wenn sie nicht (vollständig) normalisiert wird. In diesem Falle werden in der Praxis oft Redundanzen bewusst in Kauf genommen, um zeitaufwändige und komplexe Joins zu verkürzen und so die Geschwindigkeit der Abfragen zu erhöhen. Man spricht auch von einer Denormalisierung einer Datenbank. Wann (und ob überhaupt) eine Denormalisierung sinnvoll ist, ist umstritten und hängt von den Umständen ab.
Ein Merkmal der Redundanz ist, dass einzelne Werte innerhalb einer Tabelle oder Datenbank ohne Informationsverlust weggelassen werden können. Redundanz kostet nicht nur Speicherplatz, sondern kann Ursache für Anomalien (z. B. Update-, Insert-, Delete-Anomalien) sein. Diese werden auch als „Mutationsanomalien“ bezeichnet.
SQL ist keine Turing-vollständige Programmiersprache, ermöglicht also nicht die Realisierung von beliebigen Computerprogrammen. Sie kann aber mit anderen Programmiersprachen kombiniert werden, um eine Programmierung im engeren Sinne zu ermöglichen. Hierfür gibt es unterschiedliche Techniken.
Unabhängig von der verwendeten Programmiertechnik wird zwischen statischem und dynamischem SQL unterschieden.
Bei dynamischem SQL muss das Datenbanksystem die SQL-Anweisung zur Laufzeit des Programms interpretieren und den Zugriffspfad optimieren. Da dieser so genannte Parse-Vorgang Zeit in Anspruch nimmt, puffern viele Datenbanksysteme die bereits geparsten SQL-Anweisungen, um so, falls sie sich wiederholen, die Zeit für ein erneutes Parsen zu sparen. I Bei statischem SQL kann schon bei der Übersetzung der Programme bzw. beim Binden der SQL-Anweisungen an eine Datenbank (so genanntes Bind der SQL-Befehle) der optimale Zugriffsweg bestimmt werden. Damit sind kürzestmögliche Laufzeiten der Anwendungsprogramme möglich, allerdings muss der Zugriffsweg aller betroffenen Programme neu bestimmt werden, wenn sich Voraussetzungen (z. B. Statistiken) ändern (Rebind). Die Bind-Phase ist heute vor allem im Großrechner-Umfeld bekannt, die meisten Datenbanksysteme optimieren hingegen zur Laufzeit.
Es existieren eine Vielzahl von Erweiterungen des SQL-Standards.
SQL/XML ist ein ANSI- und ISO-Standard (ISO/IEC 9075-14:2006), der es ermöglicht, XML-Dokumente in SQL-Datenbanken zu speichern, mit XPath und XQuery abzufragen und relationale Datenbankinhalte als XML zu exportieren [1]. Der ISO-Standard ist nicht frei verfügbar, jedoch gibt es ein Zip-Archiv mit einer Entwurfsversion von 2008.
SQL/PSM ist ein ISO-Standard, der SQL um prozedurale Programmierkonstrukte erweitert. Sie bietet viele Erweiterungen zu den Standard-SQL-Sprachelementen. Sie erlaubt unter anderem das Programmieren von Schleifen (FOR, WHILE, REPEAT UNTIL, LOOP), Cursor, Exception-Handling, Trigger und eigenen Funktionen. Oracle implementiert diese Funktionalität unter dem Namen PL/SQL, DB2 verwendet den Begriff SQL/PL, PostgreSQL nennt es PL/pgSQL.
Die Bezeichnung SQL wird im allgemeinen Sprachgebrauch als Abkürzung für „Structured Query Language“ aufgefasst, obwohl sie laut ANSI-Standard ein eigenständiger Name ist. Die Bezeichnung leitet sich von dem Vorgänger SEQUEL ([ˈsiːkwəl], Structured English Query Language) ab, welcher von IBM in den 1970er Jahren auf der Grundlage des bahnbrechenden Artikels „A Relational Model of Data for Large Shared Data Banks“ (1970) von Edgar F. Codd entworfen wurde. IBM definierte 1976 „SEQUEL /2“ und benannte es aus rechtlichen Gründen in „SQL“ um.