SQL Server 2000 - Jürgen Bayer Informatik

Transcription

SQL Server 2000 - Jürgen Bayer Informatik
Jürgen Bayer
SQL Server 2000
Installieren und Administrieren des SQL Servers, Implementieren von Sichten,
Stored Procedures, Funktionen und Triggern
Inhaltsverzeichnis
1
Einführung
1
1.1
Einige Begriffe zuvor
1
1.2
Die Editionen
2
Die Installation
5
2
2.1
Vorbereitungen
5
2.2
Installation des SQL Servers am Beispiel der Personal Edition
7
2.3
Diensteprogramme installieren
3
SQL Server Grundlagen
15
17
3.1
Das Client-Server Konzept im Vergleich zum File-Server
17
3.2
Client-Server Fachbegriffe
18
3.3
Der grundlegende Aufbau des SQL Servers
19
3.3.1
Die Tools des SQL Servers
20
3.3.2
Datenbanken
21
4
Grundlegende Operationen
24
4.1
Starten und Stoppen des SQL Server
24
4.2
Der Enterprise Manager
25
5
Erzeugen und Bearbeiten von Datenbanken
28
5.1
Erzeugen mit dem Enterprise Manager
28
5.2
Erzeugen mit SQL
35
6
6.1
Erzeugen und Verwalten von Tabellen
Erzeugen von Tabellen mit dem Enterprise Manager
37
37
6.1.1
Die Datentypen
38
6.1.2
Primärschlüssel und Identity-Column
40
6.1.3
RowGUIDs
41
6.1.4
Indizes und Unique Constraints
41
6.2
Beziehungen zwischen Tabellen mit referentieller Integrität
49
6.3
Erstellen von Tabellen mit SQL
53
6.3.1
Primärschlüssel über mehrere Felder
54
6.3.2
Primärschlüssel mit nicht gruppiertem Index
54
6.3.3
Check-Einschränkungen
54
6.3.4
Indizes
55
6.3.5
Fremdschlüssel-Einschränkungen
55
6.3.6
Ändern von Einschränkungen
55
6.3.7
Ändern von Indizes
56
6.3.8
Informationen zu Spalten, Einschränkungen und Indizes
56
6.4
7
Ändern von Tabellen
Benutzerverwaltung
56
57
7.1
SQL Server und Windows-Authentifizierung
57
7.2
Wie verwaltet der SQL Server die Rechte
57
7.3
Feste Server-Rollen, feste Datenbank-Rollen und benutzerdefinierte DatenbankRollen 58
7.4
Anlegen und Definieren von benutzerdefinierten Datenbank-Rollen und von
Logins 59
7.4.1
Anlegen und Modifizieren von Rollen im Enterprise-Manager
60
7.4.2
Zuweisen und Verweigern von Rechten mit SQL
63
7.4.3
Anlegen und Modifizieren von Logins
64
7.5
Login
66
7.5.1
Login mit SQL Server-Authentifizierung
66
7.5.2
Login mit Windows-Authentifizierung
66
7.6
8
Spezielle Benutzernamen und Logins
Sichten, Stored Procedures, Funktionen und Trigger
68
69
8.1
Einleitendes
69
8.2
Sichten
70
8.2.1
Erstellen einer Sicht
70
8.2.2
Verwenden von Sichten
71
8.2.3
Sortierungen in Sichten
71
8.2.4
Die Check-Option
72
8.2.5
Erweiterte Sicherheit mit Sichten
72
8.2.6
Sichten verändern
73
8.3
Stored Procedures
73
8.3.1
Erstellen von Stored Procedures
73
8.3.2
Rückgabetypen einer Stored Procedure
75
8.3.3
Parameter und Variablen
75
8.3.4
Aufruf von Stored Procedures am Beispiel eines VBA-Programms
77
8.3.5
Globale Variablen
80
8.3.6
TSQL-Kontrollstrukturen
81
8.3.7
TSQL-Operatoren
83
8.3.8
Stored Procedures mit Cursor
84
8.3.9
Stored Procedures verändern
86
8.4
Funktionen
86
8.4.1
Erstellen von Funktionen
86
8.4.2
Funktionen verändern
87
8.5
Trigger
88
8.5.1
Trigger erstellen
88
8.5.2
Die logischen Tabellen inserted und deleted
89
8.5.3
Rollback eines Triggers
93
8.5.4
Verändern von Triggern
94
8.6
Debuggen von Stored Procedures, Funktionen und Triggern
94
8.6.1
Grundlagen zum Debuggen
94
8.6.2
Das Beispiel
95
8.6.3
Der TSQL-Debugger
96
8.6.4
Der Debugger von Visual Studio .NET
99
9
Administrieren des SQL Servers
104
9.1
Die Größe des Transaktionsprotokolls
104
9.2
Backup und Restore
106
9.2.1
Die Wiederherstellungs-Modelle
107
9.2.2
Backup-Strategien
108
9.2.3
Backup von Hand
109
9.2.4
Restore
111
9.3
10
Der SQL Server Agent
Tipps und Tricks
113
114
10.1
Manuelles Definieren einer Identity-Spalte für neue Datensätze
114
10.2
Temporäre Tabellen
114
11
11.1
12
Anhang
Literaturverzeichnis
Index
116
116
117
Bei der Installation und Verwendung des SQL Servers und in allen möglichen Artikeln und
Büchern werden Sie immer wieder mit einigen Begriffen konfrontiert, die Sie vielleicht noch
nicht kennen. Obwohl dieser Artikel die damit verbundenen speziellen Techniken nicht
behandelt, beschreibe ich diese kurz. Dann wissen Sie wenigstens, warum es dabei prinzipiell
geht .
Die Datenbank-Engine ist das Herz des SQL Servers. Sie verwaltet die Daten und ermöglicht
das Abfragen und Manipulieren der Daten über SQL.
OLAP (Online Analytical Processing) ermöglicht es Benutzern, Daten unter den
verschiedensten Gesichtspunkten abzufragen. So kann ein Abteilungsleiter z. B. alle
Bestellungen von Produkten einer bestimmten Kategorie abfragen, die im Juli 2003 in die USA
ausgeliefert wurden, diese mit Bestellungen von Produkten im selben Monat vergleichen, die
innerhalb von Europa verkauft wurden und das Ganze mit Bestellungen aus Vormonaten
vergleichen. OLAP ermöglicht es dem Benutzer, die Dimensionen der Abfrage (im Beispiel
sind das die Produktkategorie, der Monat und die Zielregion) dynamisch auszuwählen und
anzupassen. OLAP-Daten werden in so genannten multidimensionalen Datenbanken verwaltet,
die es erst möglichen, Daten multidimensional abzufragen. Üblicherweise werden
multidimensionale Datenbanken über spezielle Tools in regelmäßigen Abständen aus dem
Daten einer normalen (relationalen oder objektorientierten) Datenbank generiert. Die OLAPFeatures des SQL Servers bieten Unterstützung bei der Erstellung und beim Füllen von
multidimensionalen Datenbanken.
Data-Mining (»nach Daten graben«) in ist ein eher allgemeiner Begriff, der aber sehr häufig im
Zusammenhang mit Datenbanken auftaucht. Datamining wird in der Mathematik, der
Kybernetik und der Genetik u. a. verwendet um herauszufinden, welche Daten in einer
gegebenen Menge mit welchen anderen assoziiert sind und welche Daten in einer Folge von
Ereignissen zu welchen anderen Daten führen.
Bezogen auf Datenbanken ist mit Data-Mining im Prinzip dasselbe gemeint. In großen
Unternehmen werden häufig so viele Daten gespeichert, dass ein genereller Überblick darüber
nicht möglich ist. Datamining meint dann, dass in den Unternehmensdaten nach speziellen (in
den Daten zunächst verborgenen) Informationen gegraben wird. Dazu gehört zum Beispiel, zu
erkennen, nach welchem Muster Produkte verkauft werden (z. B. in welcher Region, in
welchem Monat welches Produkt besser verkauft wird als andere). Hilfreich dabei ist natürlich
OLAP.
!
In Unternehmen werden
und meist auch nicht
Unternehmen liegen
Datenbanksysteme oder
Daten normalerweise nicht ausschließlich in einer einzigen Datenbank
in einem einzigen Datenbanksystem verwaltet. In den meisten
die Unternehmensdaten verstreut auf mehrere, verschiedene
auch einfach nur in einer Vielzahl von Dateien (wie z. B. Excel-
Einführung 1
Dateien) vor. Normalerweise ist es dann sehr schwierig, wenn Daten aus verschiedenen Quellen
abgefragt werden müssen, um ein Problem zu lösen.
Data-Warehousing steht nun dafür, dass in einem Unternehmen eine zentrale (»normale«)
Datenbank in regelmäßigen Abständen mit den unterschiedlichen Unternehmensdaten oder
Extrakten daraus gefüllt beziehungsweise aktualisiert wird. Über diese, rein zum Lesen
gedachte Datenbank können die Daten des Unternehmens dann konsistent abgefragt werden.
Der SQL Server bietet Unterstützung für Data-Warehousing über die die Data Transformation
Services (DTS).
"
Der SQL Server 2000 kann auf verschiedenen Microsoft-Betriebssystemen und in
verschiedenen Editionen installiert werden. Damit Sie wissen, welche Editionen was bietet und
auf welchen Systemen Sie diese installieren können, beschreibe ich diese im Folgenden kurz.
Eine
nähere
Beschreibung
finden
Sie
im
Microsoft-Dokument
www.microsoft.com/sql/techinfo/planning/ChoosEd.doc.
#
Die Enterprise Edition bietet alle Features des SQL Servers. Sie ist extrem skalierbar und kann
für einfache Unternehmensdatenbanken, aber auch für die größten Websites, für OLTP (Online
Transaction Processing) und für Data-Warehousing-Systeme eingesetzt werden. Da diese
Edition das so genannte »Failover Clustering« ermöglicht, können damit sehr große
Datenbanken aufgebaut werden, die über mehrere Server verteilt werden und die beim Ausfall
eines Servers weiter betrieben werden können. Die Enterprise Edition bietet Unterstützung für
Rechner mit maximal 32 Prozessoren und bis zu 64 GB Arbeitsspeicher. Sie kann auf den
folgenden Betriebssystemen installiert werden:
•
Windows 2000 Server
•
Windows 2000 Advanced Server
•
Windows 2000 Datacenter Server
•
Windows NT Server 4.0
•
Windows NT Server 4.0 Enterprise Edition
$
Diese Edition ist für kleinere und mittlere Unternehmen gedacht, die die erweiterte
Skalierbarkeit, Verfügbarkeit und Performance und die erweiterten Analyse-Features der
Enterprise Edition nicht benötigen. Ansonsten sind aber alle Features des SQL Servers, wie z.
B. Standard-OLAP-Features, alle Data-Mining-Features und alle XML-Features enthalten. Die
Standard Edition bietet gegenüber der Enterprise Edition u. a. die folgenden Features nicht:
•
erweitertes OLAP
•
auf mehrere Server verteilte Sichten auf die Daten
•
hohe Verfügbarkeit
•
indizierte Sichten
•
Analyse (OLAP) über das Web
Die Standard Edition bietet Unterstützung für Rechner mit maximal vier CPUs und 2 GB
Arbeitsspeicher und kann denselben Betriebssystemen installiert werden, wie die Enterprise
Edition.
Einführung 2
Die Personal Edition ist für den Standalone-Betrieb auf einem Desktop-PC oder einem
Notebook vorgesehen. Sie ist gedacht für Anwendungen, die einen installierten SQL Server
benötigen, aber auf Computern ausgeführt werden, die (evtl. nur zeitweise) nicht mit einem
Server dem Unternehmen verbunden sind. Die Personal Edition beinhaltet prinzipiell dieselben
Features wie die Standard Edition, mit den folgenden Ausnahmen:
•
Wenn mehr als fünf SQL-Anweisungsstapel gleichzeitig ausgeführt werden, wird die
Performance automatisch reduziert;
•
Die Personal Edition kann lediglich zwei Prozessoren und maximal 2 GB Arbeitsspeicher
nutzen (auf Windows 98 oder Me nur einen Prozessor);
•
Die Personal Edition kann nicht als »Verleger« (Subscriber) in einem replizierten System
verwendet werden.
Sie können die Personal Edition auf den folgenden Betriebssystemen installieren:
•
Windows XP Professional
•
Windows 2000 Professional
•
Windows 2000 Server
•
Windows 2000 Advanced Server
•
Windows 2000 Datacenter Server
•
Windows NT Workstation
•
Windows NT Server 4.0
•
Windows NT Server 4.0 Enterprise Edition
#
Die Developer Edition ist prinzipiell identisch mit der Enterprise Edition und mit einer
speziellen Lizenz versehen, die es Entwicklern erlaubt, mit dieser Editionen zu entwickeln und
zu testen. Als Unternehmens-Server darf diese Edition natürlich nicht eingesetzt werden.
Installiert werden kann die Developer Edition auf:
•
Windows XP Professional
•
Windows 2000 Professional
•
Windows 2000 Server
•
Windows 2000 Advanced Server
•
Windows 2000 Datacenter Server
•
Windows NT Workstation
•
Windows NT Server 4.0
•
Windows NT Server 4.0 Enterprise Edition
!
% &
Die Windows CE Edition ist eine Version des SQL Servers, die unter Windows CE auf PocketPCs ausgeführt werden kann. Sie bietet lediglich einen grundlegenden Satz Funktionalität, wie
z. B. grundlegende Features für relationale Datenbanken, Support für Transaktionen, RemoteDatenbankzugriff und für Replikationen.
Die Windows CE Edition kann unter Windows CE ab Version 2.11 installiert werden.
Einführung 3
#
' $
(
Die MSDE ist eine Version des SQL Servers, die nur den eigentlichen Datenbank-Server
enthält. Alle erweiterten Features wie z. B. OLAP und alle Werkzeuge des SQL Servers (wie z.
B. der Enterprise Manager) fehlen. Der SQL Server Agent, der für zeitgesteuerte Aufgaben, wie
z. B. ein regelmäßiges Backup verwendet wird, ist allerdings in der MSDE enthalten. Im Prinzip
ist diese Edition vergleichbar mit der Personal Edition, benötigt aber weniger Speicher. Das
besondere an der MSDE ist, dass diese frei verteilt werden kann. Ein Entwickler, der eine
Anwendung vertreiben will, die auf einer SQL-Server-Datenbank basiert, kann die MSDE der
Installations-Version seiner Anwendung ohne weitere Kosten beilegen.
Die MSDE können Sie auf den folgenden Betriebssystemen installieren:
•
Windows XP Professional
•
Windows 2000 Professional
•
Windows 2000 Server
•
Windows 2000 Advanced Server
•
Windows 2000 Datacenter Server
•
Windows NT Workstation
•
Windows NT Server 4.0
•
Windows NT Server 4.0 Enterprise Edition
Einführung 4
"
"
)
*
Bevor Sie den SQL Server installieren sollten Sie einige Dinge überprüfen:
$
Da das Installationsprogramm per Voreinstellung den aktuellen Computernamen als
Servername verwendet, sollte dieser der SQL-Konventionen entsprechen. Der Name darf nur
Buchstaben, Zahlen, Unterstriche, Hashes (#) und das Ampersand (&) enthalten und das erste
Zeichen muss ein Buchstabe sein. Sie können den SQL Server aber auch so installieren, dass
dieser nicht den Computernamen verwendet, sondern einen spezifischen.
+ ,
$- $
Der SQL Server verwendet zwei Dienste, die auf dem lokalen Rechner mit AdministratorRechten ausgestattet sein müssen (den SQL Server-Dienst und den SQL Server Agent-Dienst).
Bei der Installation müssen Sie für beide Dienste entweder das System-Konto oder ein
Benutzerkonto mit Administrationsrechten angeben. Sie können dabei wählen, ob beide Dienste
unter demselben Konto oder unter unterschiedlichen Konten laufen. Sie sollten für diese Dienste
ein oder zwei spezielle Benutzerkonten einrichten, deren Kennwort nicht abläuft und die das
Kennwort nicht ändern können. Verwenden Sie auf keinen Fall ein Konto eines Benutzers (wie
z. B. das Administrator-Konto). Wenn der entsprechende Benutzer sein Kennwort später ändert,
können die Dienste ihre Arbeit nicht mehr aufnehmen.
,
*
)
Der SQL Server 2000 erfordert die Installation des Internet Explorers ab Version 5.0. Unter NT
ist zudem das Service Pack ab Version 5 erforderlich.
.
%
Der SQL Server sollte auf einem System mit mindestens 64 MB Arbeitsspeicher installiert
werden. Für die MSDE empfiehlt Microsoft mindestens 32 MB, für die Enterprise Edition
mindestens 128 MB. An Festplattenspeicher benötigt der SQL Server 95 bis 250 MB. Da der
SQL Server einmal abgefragte Daten in einem Cache zwischenspeichert, so dass diese bei der
nächsten Abfrage wesentlich schneller verfügbar sind, sollten Sie so viel Arbeitsspeicher
einbauen, wie möglich, wenn der SQL Server in einem Unternehmen eingesetzt wird.
Da der SQL Server sehr prozessorintensiv arbeitet, empfiehlt sich der schnellste auf dem Markt
erhältliche Prozessor. Wenn weniger als 100 Clients gleichzeitig auf den Server zugreifen,
reicht ein Prozessor aus. Bei mehr als 100 Clients sollten Sie ein Mehrprozessorboard
vorziehen. Der Windows-Performance Monitor hilft Ihnen mit der Anzeige der ProzessorVerwendung bei der Entscheidung, ob zusätzliche oder schnellere Prozessoren eingebaut
werden müssen. Wenn das System durchschnittlich 70% oder für mindestens zehn Sekunden
90% des Prozessors verwendet, sollten Sie einen schnelleren oder einen zusätzlichen Prozessor
einbauen.
Bei den Festplatten sollten Sie auf jeden Fall SCSI einsetzen, besonders dann, wenn mehrere
Platten eingebaut sind. Beim gleichzeitigen Zugriff auf mehrere Platten belastet SCSI den
Prozessor weit weniger als IDE. IDE-Geräte können nicht gleichzeitig angesprochen werden,
der Prozessor muss immer ein Gerät nach dem anderen ansprechen. Das ist besonders dann
performance-mindernd, wenn ein (langsames) IDE-CD-ROM vorhanden ist und gleichzeitig mit
einer Festplatte angesprochen wird. Ein SCSI-Controller sendet Anforderungen hingegen in
eine Warteschlange im SCSI-Gerät. Das SCSI-Gerät meldet den Abschluss der Anforderung an
Die Installation 5
den Controller zurück, der die Daten dann an den Prozessor weitergibt. So können gleichzeitig
mehrere Anforderungen bearbeitet werden.
In kleineren Unternehmen reicht eine Platte aus, die jedoch aus Sicherheitsgründen auf eine
zweite Platte gespiegelt werden sollte (RAID 1). Bei hohen Datenanforderungen können Sie
einzelne Datenbanken und auch Teile von Datenbanken (einzelne Tabellen und/oder das
Transaktionsprotokoll) auf verschiedenen Platten erstellen, um den gleichzeitigen Zugriff zu
beschleunigen. Die ideale Lösung (vgl. Delaney) ist die Installation des (sequentiell
organisierten) Transaktionsprotokolls auf einem RAID 1-System und der Datenbanken auf
einem separaten RAID 0+1-System1.
Eine sehr ausführliche Abhandlung zu den Hardwareanforderungen finden Sie im
Buch »Inside SQL Server 2000« von Kalen Delaney (ISBN 3860636197).
Zur Installation müssen Sie als Administrator eingeloggt sein.
1
RAID 0 benutzt zwei Festplatten, die dem System als eine dargestellt werden. Daten werden in
festgelegten Blöcken auf den beiden Platten verteilt. So wird die Performance von zwei Platten zur
Speicherung und zum Lesen genutzt. Ein RAID 0,1-System spiegelt ein RAID-0-System zusätzlich auf
ein weiteres RAID-0-System. Damit erhalten Sie gleichzeitig eine hohe Performance und eine hohe
Sicherheit.
Die Installation 6
"" )
$- $
#
Nachdem Sie die Datei autorun.exe auf der Installations-CD aufgerufen haben, öffnet sich der
Startdialog, in dem Sie neben der Installation auch einige Informationen abrufen können.
Klicken Sie auf den Link SQL SERVER 2000-KOMPONENTEN © um die Installation zu starten.
Im folgenden Dialog erhalten Sie die Möglichkeit, den Datenbank-Server und weitere
Komponenten des SQL Servers wie z. B. die Analyse-Dienste (Analysis Services) und English
Query zur installieren.
Abbildung 1: Auswahl der zu installierenden Komponenten
Den Datenbank-Server (den eigentlichen SQL Server) müssen Sie zumindest installieren. Die
Analyse-Dienste und English Query sind optional. Die Analyse-Dienste bieten spezielle
Features zur Verwendung von OLAP- und Datamining-Anwendungen. English Query ist ein
spezielles Tool, das es Anwendern ermöglicht, Datenbanken mit nahezu normaler englischer
Sprache an Stelle von SQL abzufragen.
Klicken Sie also auf den Link DATENBANKSERVER INSTALLIEREN um den eigentlichen SQL
Server zu installieren. Bestätigen Sie den Willkommens-Dialog und wählen Sie im nächsten
Schritt, ob Sie den Server auf dem lokalen Computer oder auf einem entfernten Rechner
installieren wollen.
Im folgenden Schritt sollten Sie die erste Option wählen wenn Sie den SQL Server neu
installieren. Die Option ERWEITERTE OPTIONEN ermöglicht im Vergleich dazu lediglich die
Aufzeichnung einer speziellen »ISS«-Datei zur späteren unbeaufsichtigten Installation und die
Wiederherstellung der Registrierung.
Die Installation 7
Abbildung 2: Auswahl der Option zur Installation des SQL Servers
Nachdem Sie in den folgenden Schritten ihren Namen eingegeben und der Lizenzvertrags
bestätigt haben, können Sie wählen, ob Sie den Server komplett (inklusive MDAC und den
Client-Tools zur Administration des Servers), nur die Client-Tools oder nur die Tools, die eine
Verbindung zum SQL Server ermöglichen (MDAC, die »Microsoft Data Access Components«)
installieren wollen. Für eine normale Installation wählen Sie die zweite Option.
Abbildung 3: Auswahl der Server- und Cienttools für eine normale Installation
Die Installation 8
Der nächste Schritt ermöglicht es, einen speziellen Instanznamen für den SQL Server
einzurichten.
Abbildung 4: Auswahl der Server- und Cienttools für eine normale Installation
Ab der Version 2000 ermöglicht der SQL Server es, mehrere Instanzen auf einem Computer
auszuführen. Standardmäßig wird eine Instanz benannt wie der Computer selbst. Wenn Sie eine
weitere Instanz installieren, oder wenn Sie die Instanz anders benennen wollen, können Sie
einen speziellen Instanznamen eingegeben. Ist bereits eine Instanz des SQL Servers (ab Version
7) mit dem Standardnamen installiert, müssen Sie sogar einen speziellen Instanznamen
verwenden.
Im nächsten Schritt können Sie die Installationsart und den Installationsort wählen. Wählen Sie
die Option BENUTZERDEFINIERT um bei der Installation alle Optionen einstellen zu können.
Die Installation 9
Abbildung 5: Auswahl der Installationsart und des Installationsortes
Nachdem Sie auf WEITER geklickt haben können Sie nun die zu installierenden Komponenten
wählen.
Abbildung 6: Auswahl der zu installierenden Komponenten
Schalten Sie die Option VOLLTEXTSUCHE ein, wenn Sie eine Volltextsuche ermöglichen
wollen. Die Volltextsuche geht weit über die Möglichkeiten des LIKE-Operators in SQLAbfragen hinaus. Für die Komponente ENTWICKLUNGSTOOLS sollten Sie gegebenenfalls die
Option API ZUM SICHERN/WIEDERHERSTELLEN einschalten. Mit dieser API können Sie externe
Programme schreiben, die Datenbanken sichern bzw. wiederherstellen ohne den Enterprise
Manager dazu zu verwenden.
Die Installation 10
Im nächsten Schritt geben Sie ein oder mehrere Benutzerkonten an, unter denen die Dienste des
SQL Servers ausgeführt werden sollen. Der SQL Server besteht im Wesentlichen aus den
Diensten SQL Server (der SQL Server selbst) und SQL Server Agent (Dienst für zeitgesteuerte
Jobs wie z. B. automatische Backups). Sie können für beide Dienste entscheiden ob diese unter
dem Systemkonto oder unter einem speziellen Konto ausgeführt werden sollen.
Abbildung 7: Einstellung der Konten für die SQL Server-Dienste
Die Verwendung des Systemkontos ist dann ausreichend, wenn der SQL Server nicht auf
andere, entfernte SQL Server zugreifen muss (was z. B. bei verteilten Datenbanken und bei
Replikationen notwendig ist). Im anderen Fall sollten Sie ein oder zwei spezielle Konten für die
Dienste des SQL Servers einrichten und diese mit (Domänen-)Administrationsrechten
ausstatten. Verwenden Sie kein vorhandenes Benutzerkonto, bei dem es möglich ist, dass der
Benutzer das Passwort ändert, da die Dienste des SQL Servers in diesem Fall nicht mehr starten.
Die in diesem Dialog vorgenommenen Einstellungen können Sie später aber auch über den
Windows-Dienste-Manager anpassen.
Nach der Einstellung der Dienste-Konten wählen Sie, welchen Authentifizierungsmodus der
SQL Server ermöglicht.
Die Installation 11
Abbildung 8: Einstellung des Authentifizierungsmodus
Hier sollten Sie den gemischten Modus einstellen und ein Kennwort für den
Systemadministrator eingegeben. Die Windows-Authentifizierung ermöglicht es Benutzern,
sich mit deren Windows-Login direkt auch in den SQL Server einzuloggen. Das erleichtert
späteren Benutzern in einem Windows-System (idealerweise mit einer Domäne, in der die
Benutzer verwaltet werden) die Arbeit mit Anwendungen, die Daten im SQL Server verwalten.
Benutzer müssen sich dann nicht separat am SQL Server anmelden. Bei der anderen Art der
Authentifizierung, der SQL-Server-Authentifizierung, werden dagegen spezielle Login-Namen
im SQL Server verwaltet. Anwendungen, die diesen Modus verwenden, müssen sich explizit
über einen dieser Namen im SQL Server einloggen. Da Sie beide Modi ermöglichen, können
Sie den SQL Server auch dann administrieren wenn auf dem Computer, auf dem Sie die ClientTools verwenden, kein Administrator eingeloggte ist.
Vergeben Sie dann aber auf jeden Fall ein nicht zu einfaches Kennwort für den
Systemadministrator. Der Systemadministrator (der gleichzeitig auch mit dem
Windows-Benutzer Administrator assoziiert wird) besitzt alle Rechte auf dem SQL
Server und darf damit Aktionen ausführen, die auch zur Zerstörung einer
Datenbank führen können.
Im nächsten Schritt können Sie die Sortierung einstellen, die standardmäßig für
Datenbankabfragen verwendet werden soll.
Die Installation 12
Abbildung 9: Einstellung des Standardsortierung
Die Sortierung bezieht sich auf SQL-Abfragen mit ORDER BY, GROUP BY oder ähnlichen
Anweisungen. Die voreingestellten Werte entsprechen der Sortierung, die in Deutschland
normalerweise verwendet wird. Sie können für Datenbanken, die mit anderen Systemen
kommunizieren sollen, auch eine andere Sortierung einstellen. Das Hauptkriterium dazu ist der
links oben einstellbare Unicode-Zeichensatz. Es ist verständlich, dass die chinesische Schrift
eine vollkommen andere Sortierung besitzt als die westlichen Schriften, die mit dem
Zeichensatz ISO Latin 1 (der der Einstellung LATIN1_GENERAL entspricht) abgebildet werden.
Zusätzlich dazu können Sie noch einstellen, ob bei der Sortierung Groß- und Kleinschreibung
und andere spezielle Dinge berücksichtigt werden.
Zeichen-Vergleich
Bedeutung
Binär
Wenn Sie diese Option einschalten (die alle anderen
ausschließt) sortiert der SQL Server nach dem UnicodeWert der Zeichen.
Groß-/Kleinschreibung beachten
Groß- und Kleinbuchstaben werden unterschiedlich
gewertet
Unterscheidung nach Akzent
Buchstaben mit Akzenten (z. B. á, à) werden ungleich
Buchstaben ohne Akzenten gewertet
Tabelle 1: Wichtige Sortierungs-Optionen
Die Unterscheidung nach Kana ist für die japanische Sprache, die Unterscheidung nach Breite
für bestimmte ostasiatische Sprachen wichtig.
Im nächsten Schritt geben Sie an, welche Netzwerk-Bibliotheken installiert werden sollen.
Voreingestellt ist TCP/IP.
Die Installation 13
Abbildung 10: Einstellung der Netzwerk-Bibliotheken
•
Named Pipes ist kein Protokoll, sondern ein IPC2-Mechanismus, der auf verschiedenen
Betriebssystemen verfügbar ist (z. B. neben Windows- auch auf UNIX- und LinuxSystemen). Named Pipes wird für die Kommunikation zwischen Prozessen verwendet, die
auf demselben Computer ausgeführt werden. Damit ermöglicht Named Pipes ein Arbeiten
mit dem SQL Server ohne ein funktionstüchtiges Netzwerk und hält Ihnen so eine Hintertür
zum SQL Server offen für den Fall, dass das Netzwerk ausfällt. Wählen Sie dieses Protokoll
also nicht ab.
•
TCP/IP-Sockets verwendet das TCP/IP-Protokoll zur Kommunikation mit dem Client.
Laut Tests bei Microsoft ist dieses Protokoll das schnellste. Zudem müssen Sie das TCP/IPProtokoll verwenden, wenn der SQL Server über das Internet von Clients direkt3
angesprochen werden soll oder wenn Sie den SQL Server mit bestimmten Web-ServerAnwendungen, wie dem Microsoft Site Server verwenden. Installieren Sie dieses Protokoll
also auf jeden Fall. Der per Default eingestellte Port 1433 ist der Standard-Port für den SQL
Server. Nur wenn Sie mehrere SQL Server-Instanzen installieren macht es Sinn (bzw. ist
notwendig), dass Sie den Port anpassen.
•
Multi-Protocol ist wie Named Pipes ebenfalls kein Protokoll, sondern ein IPCMechanismus, der verschiedene andere Protokolle (wie z. B. TCP/IP) verwenden kann.
Multi-Protocol ermöglicht als einzige Bibliothek die Verschlüsselung von Daten zwischen
Server und Client. Wenn ein SQL Server im Internet verfügbar sein soll, ist die
Verschlüsselung oft ein wesentlicher Aspekt der Datensicherheit. Da Sie die MultiProtocol-Bibliothek so einstellen können, dass diese das TCP/IP-Protokoll verwendet,
können Sie so z. B. auch im Internet Sicherheit gewährleisten.
2
Interprocess Communication
3
direkt meint, ein Client baut eine Verbindung zu einer SQL Server-Datenbank über das Internet auf, was
in der Praxis eigentlich unüblich ist. Sinnvoll wäre die direkte Verbindung z.B., um einen SQL Server
über das Internet administrieren zu können. Der Zugriff auf die Daten erfolgt im Internet üblicherweise
über Mechanismen wie Active Server Pages (ASP) oder CGI-Skripts (die beide die Verbindung auf dem
Web-Server aufbauen, der in der Regel eine direkte Netzverbindung zum SQL Server besitzt).
Die Installation 14
•
NWLink IPX/SPX müssen Sie installieren wenn das Netzwerk ein Novell-Netz ist.
•
AppleTalk ADSP müssen Sie installieren wenn Apple-Rechnern als Client auf den SQL
Server zugreifen sollen.
•
Banyan VINES müssen Sie installieren wenn Rechner mit einem entsprechenden
Betriebssystem als Client auf den SQL Server zugreifen sollen.
Nachdem Sie diesen letzten Schritt bestätigt haben sind alle Einstellungen vorgenommen und
der SQL Server beginnt (nach einem weiteren Info-Dialog) mit der Installation.
"/
#
Auf dem Server werden die notwendigen Diensteprogramme beim Setup per Voreinstellung
automatisch mitinstalliert. Auf einem Client-Computer können Sie aber auch eine
ausschließliche Diensteprogramm-Installation ausführen um die für die Administration
notwendigen Tools auch auf einem anderem Rechner zur Verfügung zu haben. Tabelle 2
beschreibt die wichtigsten der Client-Diensteprogramme.
Diensteprogramm
Bedeutung
Enterprise Manager
Der Enterprise Manager ist das wichtigste Werkzeug zur
Verwaltung des SQL Servers. Über dieses Programm können
Sie alle administrativen Aufgaben ausführen.
Profiler
Der Profiler ist ein Tool zur Auswertung der
Datenbankaktivitäten und zum Tuning und zur Überwachung
der Leistung des SQL-Servers.
Query Analyzer
Der Query Analyzer ist ein wichtiges Windows-Programm zur
einfachen Ausführung von SQL-Anweisungen.
Tabelle 2: Die wichtigen Client-Diensteprogramme des SQL Servers
Um diese Tools zu installieren starten Sie das Setup wie eine normale Installation und wählen
dann in Schritt 6 die Option NUR CLIENTTOOLS.
Die Installation 15
Abbildung 11: Installation der Client-Tools
Die Installation 16
/ $- $
0
/
$
&
2
1
#
*
,
$
Beim klassischen File-Server übernimmt der Server lediglich die Aufgabe die Daten zu
speichern und zu verwalten. Die Bearbeitung und Darstellung der Daten wird mit Hilfe einer
Anwendung auf einem Client ausgeführt. Diese Vorgehensweise besitzt einige Nachteile:
• die Netzbelastung ist sehr hoch;
•
die Wahrung der Datenintegrität und Konsistenz verbleibt größtenteils bei den Clients;
•
die Verwaltung der Benutzerrechte verbleibt bei den Clients.
3
Wenn ein Client Daten nach bestimmter Kriterien auswählen und anzeigen will ist beim FileServer-Konzept notwendig, dass im Idealfall zunächst nur die komplette Indexdatei über das
Netz zum Client übertragen werden muss, damit dieser in der lokalen Kopie suchen kann. Kann
nicht im Index gesucht werden, ist sogar die Übertragung der kompletten Datentabelle über das
Netz notwendig. Wurde nur die Indexdatei geladen ist für jede Bewegung zwischen den
Datensätzen wieder die Übertragung von einzelnen Datensätzen über das Netz notwendig.
Obwohl moderne DBMS die Netzbelastung sicherlich durch intelligente Techniken reduzieren,
ist diese dennoch sehr hoch. Die Ausführungsgeschwindigkeit der einzelnen Operationen hängt
sehr von der Ausstattung der Einzelplatz-PCs und der Qualität des Netzwerks ab.
Beim Client/Server-Konzept übernimmt der Server die Verwaltung der Daten und stellt den
Clients auf Anfrage die gewünschte Datenmenge zur Verfügung. Als Abfragesprache dient
SQL. Hier müssen lediglich die SQL-Anweisung und schließlich nur die Daten, die den
Kriterien entsprechen, über das Netz transportiert werden. Die Ausführungsgeschwindigkeit
hängt im Wesentlichen von der Ausstattung und Auslastung des Servers ab, die ClientComputer kommen mit relativ wenig Performance aus.
4
1
Ein Client-Server-Konzept besitzt im Server in der Regel wesentlich mehr Möglichkeiten zur
Wahrung der Integrität und Konsistenz der Daten. Der SQL Server besitzt die folgenden
Features zur Wahrung der Datenintegrität:
•
Datentypen, die den Typ der Daten festlegen, die in ein Datenfeld eingegeben werden
können.
•
Regeln, die definieren, welche Werte in Datenfeldern eingegeben werden können (z. B.
eine Artikelnummer nur zwischen 10.000 und 99.999).
•
Check Constraints, die Regeln ähnlich sind, im Gegensatz dazu jedoch mehrere
Datenfelder einbeziehen können.
•
Deklarierte Referentielle Integrität (DRI), mit der Beziehungen mit referentieller
Integrität zwischen Tabellen erstellt werden können.
•
Trigger, die bei einem Update, Insert oder Delete auf einer Tabelle TSQL-Skripts
ausführen können und damit z. B. komplexe Referentielle Integrität gewährleisten oder
laufende Summen berechnen können.
SQL Server Grundlagen 17
/" &
$
2,
* %
Views (Sichten) sind lediglich eine andere Betrachtungsform einer oder mehrerer Tabellen.
Views zeigen bestimmte Felder einzelner oder mehrere Tabellen gleichzeitig in einer
temporären Ansicht. Auf Views können bis auf wenige Ausnahmen dieselben Operationen
angewendet werden wie auf Tabellen. Ändert ein Anwender Daten in einer Sicht, so werden die
zugrunde liegenden Tabellen entsprechend angepasst.
$
,
Eine Stored Procedure (Gespeicherte Prozedur) ist eine vorkompilierte Folge von SQLAnweisungen, die unter dem Namen der Prozedur von außen aufgerufen werden können. Der
Microsoft SQL Server besitzt standardmäßig einige Gespeicherte Prozeduren, deren Name mit
sp_ (Systemprozeduren) und xp_ (Erweiterte Systemprozeduren) beginnt. Benutzerdefinierte
Stored Procedures werden verwendet, um die Performance für Abfragen zu erhöhen (Stored
Procedures müssen im Gegensatz zu SQL-Abfragen nicht immer wieder kompiliert werden) und
um Teile der Businesslogik4 einer Anwendung auf den Server auszulagern und damit leichter
pflegbar zu machen.
5
Ein Trigger ist eine spezielle Stored Procedure, die immer dann automatisch aufgerufen wird,
wenn eine Tabelle durch ein definiertes Ereignis verändert wird. Ein Trigger kann damit z. B.
die Businesslogik (Business Rules) in der Datenbank aufrechterhalten. So ist die Abbuchung
eines Artikels vom Lagerbestand z. B. nur dann möglich, wenn der Artikel lieferbar ist.
Außerdem ist mit Triggern die Erhaltung der Referentiellen Integrität möglich wenn der Server
keinen eigenen Mechanismus dazu besitzt (was bei modernen Systemen jedoch der Fall ist) oder
der Mechanismus anders definiert werden soll als der Server-eigene Mechanismus.
+
'+
(
Regeln definieren, welche Daten in einzelnen Spalten einer Tabelle eingegeben werden können.
Bei jeder Eingabe oder Änderung (INSERT oder UPDATE) eines Wertes überprüft der SQL
Server den Wert mit Hilfe der für das betreffende Feld definierte Regel.
, 4
'&
(
Einschränkungen entsprechen dem ASCII-Standard und begrenzen die möglichen Werte, die in
eine oder mehrere Spalten einer Tabelle eingegeben werden können. Einschränkungen können
gleichzeitig mehreren Spalten zugewiesen werden.
6#
Neben den Standarddatentypen können Sie eigene Datentypen definieren, die auf den
Standarddatentypen basieren. Diese Benutzerdefinierte Datentypen können Sie als Datentyp für
4
Die Businesslogik definiert, wie und mit welchen Rechten auf Unternehmensdaten zugegriffen werden
kann. In klassischen 2-Schichten-Systemen, die eine Desktop-Datenbank verwenden, ist die
Businesslogik zwangsweise in den Clients implementiert. Client/Server-Datenbanken ermöglichen, Teile
der Businesslogik über Stored Procedures und Trigger auf den Datenbankserver auszulagern und damit
die Pflege der Businesslogik erheblich zu erleichtern. In modernen 3- oder n-Schichten-Systemen wird
die Businesslogik übrigens in der mittleren Schicht, der Businesslogik-Schicht, in Form von COM- bzw.
CORBA-Objekten untergebracht. Stored Procedures spielen jedoch auch hier eine Rolle.
SQL Server Grundlagen 18
Spalten und Parameter für Gespeicherte Prozeduren verwenden. Benutzerdefinierte Datentypen
unterscheiden sich in den verschiedenen DBMS.
//
$- $
Der SQL Server besteht aus mehreren Diensten, die bei Windows XP, 2000 und NT als Dienst
und bei Windows 98 und Me als exe-Datei vorliegen. Der MSSQLServer-Dienst arbeitet auf der
untersten Ebene, verwaltet alle Dateien, aus denen die Datenbanken aufgebaut sind und ist dafür
verantwortlich, SQL-Anweisungen zu verarbeiten, Ergebnisse zu den Clients zurückzusenden
und Systemressourcen zu allozieren. Der SQLServerAgent-Dienst führt zeitgesteuerte Jobs aus
und ist für Warnungen zuständig. Ein zeitgesteuerter Jobs kann z. B. das tägliche Backup der
Datenbank sein. Der Microsoft Distributed Transaction Coordinator (MSDTC) ist
verantwortlich für die Koordination von Transaktionen, die über mehrere (u. U. entfernte)
Datenbanken ausgeführt werden.
Auf den Clients und dem Server laufen zudem eine Client- und eine Server-NetzwerkBibliothek, die die Verbindung mit den Clients über das Netzwerk ermöglichen und auf dem
Server der Open Data Service (ODS), eine Schnittstelle zwischen der Netzwerkbibliothek und
dem MSSQLServer-Dienst.
Auf der Clientseite kann ein Client über verschiedene Komponenten Verbindung mit dem
Server aufnehmen: über ODBC (direkt oder über DAO, RDO oder ADO), OLE DB (ADO),
ADO.NET und über die SQL Server DB-Bibliotkek. Im Hinblick auf zukünftige Entwicklungen
und die Erweiterbarkeit einer Anwendung sollte der Zugriff wohl ausschließlich über ADO oder
ADO.NET erfolgen. Die Microsoft Data Access Components (MDAC), von denen ADO ein
Bestandteil ist, beinhalten einen nativen Provider für den SQL Server. Der SQL Server 2000
installiert MDAC 2.6 bereits auf dem Server. Sie können die aktuelle MDAC-Version außerdem
von der Microsoft Website herunterladen (www.Microsoft.com/data). ADO.NET, das
Bestandteil des .NET-Framework ist, enthält ebenfalls einen nativen Provider.
SQL Server Grundlagen 19
//
5
$- $
Eine komplette Installation des SQL-Servers installiert einige Tools, die in Tabelle 3
beschrieben werden. Diese Tools finden Sie im Ordner 80\Tools\Binn der SQL ServerInstallation, sofern diese nicht über den Eintrag im Startmenü verfügbar sind.
Tool
Bedeutung
Enterprise Manager
Der Enterprise Manager (SQL Server Enterprise Manager.msc) ist das
wichtigste Werkzeug zur Verwaltung des SQL Servers. Dieses
Microsoft Management Console (MMC)-Tool ermöglicht es dem
Administrator, alle Einstellungen des SQL Servers und der
Datenbanken anzupassen und Datenbanken inklusive deren Tabellen
anzulegen und zu modifizieren.
Profiler
Der Profiler (profiler.exe) ist ein Tool zur Auswertung der
Datenbankaktivitäten, zum Tuning und zur Überwachung der Leistung
des SQL-Servers.
Query Analyzer
Der Query Analyzer (isqlw.exe) ist ein sehr wichtiges WindowsProgramm zur einfachen Ausführung von SQL-Anweisungen.
BCP
Das
Bulk
Copy
Programm
(bcp.exe)
wird
zum
kommandozeilenbasierten Im- und Exportieren von Daten zwischen
SQL Server-Datenbanken und Textdatenbanken verwendet.
DTS
DTS (Data Transformation Service) ist ein einfach zu verwendendes
Windows-Tool (dtsrunui.exe) zum Import und Export von Daten
zwischen verschiedenen Datenbanken. Da DTS auf OLE DB basiert,
können Sie damit Daten zwischen allen Datenbanken austauschen, für
die ein OLE DB-Provider verfügbar ist (z. B. SQL Server-, Oracle-,
Access- und alle Datenbanken, für die ein ODBC-Treiber verfügbar
ist). DTS wird vorwiegend für Data-Warehousing-Szenarien
eingesetzt, bei denen Daten externer Datenquellen in eine SQLServer-Datenbank importiert werden.
SQL Server
Clientkonfiguration
Die SQL Server-Clientkonfiguration (cliconfg.exe im WindowsSystemordner) wird verwendet, um die von Clients zu verwendende
Netzwerk-Bibliothek einzustellen. Viele von den Clients verwendete
Bibliotheken, wie z. B. ODBC ermöglichen eine separate Einstellung
der Netzwerk-Bibliothek, hier benötigen Sie dieses Tool nicht.
SQL ServerNetzwerkkonfiguration
Die SQL Server-Netzwerkkonfiguration (svrnetcn.exe) ermöglicht
Ihnen die Einstellung der zu verwendenden Netzwerk-Bibliotheken
auf dem Server.
Service Manager
Der Service Manager (sqlmangr.exe) ist ein einfaches Tools zum
Starten, Stoppen und Beenden der SQL Server-Dienste.
Tabelle 3: Die Diensteprogramme des SQL Servers
Die meisten dieser Tools können Sie auch über das EXTRAS-Menü des Enterprise
Managers aufrufen.
SQL Server Grundlagen 20
//"
Jede SQL Server-Datenbank ist in mindestens zwei Dateien gespeichert, der Datenbankdatei
und der Datei für das Transaktions-Protokoll (siehe unten). Eine Datenbank kann aber auch auf
mehrere Dateien aufgeteilt werden, was bei großen Datenbanken sinnvoll sein kann, wenn statt
einer großen Festplatte aus Performancegründen mehrere kleine Festplatten verwendet werden.
Der SQL Server installiert per Default die folgenden Datenbanken:
Datenbank
Bedeutung
master
In dieser Datenbank wird der SQL Server verwaltet. So sind z. B. die
Benutzerkonten, derzeit laufende Prozesse, Systemfehlermeldungen und
Informationen über die Datenbanken des Servers in der master-Datenbank
gespeichert.
model
Diese Datenbank wird als Voreinstellung für die Erzeugung neuer Datenbanken
verwendet. Neue Datenbanken erhalten die Struktur, die in der modelDatenbank voreingestellt ist. Sie können die Struktur der model-Datenbank an
Ihre Bedürfnisse anpassen, wenn das auch nur selten Sinn macht.
msdb
Der SQL Server Agent und dessen Konfigurationstools verwenden diese
Datenbank zur Speicherung der auszuführenden Jobs und der zu
überwachenden Systemwerte.
Northwind
Eine Beispieldatenbank, die Bestelldaten speichert
Pubs
Eine Beispieldatenbank, die Daten über Computer-Literatur verwaltet und im
Aufbau der biblio.mdb von Visual Basic ähnelt.
tempdb
In dieser Datenbank legt der SQL Server intern temporäre Tabellen an, die beim
Sortieren und bei einigen Verknüpfungsoperationen benötigt werden. Zudem
werden explizit erzeugte temporäre Tabellen ebenfalls in der tempdb-Datenbank
angelegt. Die tempdb-Datenbank wird bei jedem Neustart des SQL Servers neu
erzeugt.
Tabelle 4: Die Default-Datenbanken des SQL Servers
Sie sollten niemals Änderungen direkt in der master- und der msdb-Datenbank
vornehmen. Alle notwendigen Einstellungen können Sie auch über SQL oder den
Enterprise-Manager vornehmen. Änderungen in diesen Datenbanken können ein
Fehlverhalten des SQL Servers oder im schlimmsten Fall einen Ausfall des SQL
Servers verursachen.
5
#
'5
,
(
Als Transaktion bezeichnet man in der Client Server-Welt eine Gruppe von
Datenbankoperationen, die eine logische Einheit bilden. Diese Gruppe kann nur komplett
ausgeführt werden. Bei einem Fehler innerhalb der Transaktion werden alle bereits ausgeführten
Operationen rückgängig gemacht. Dies gewährleistet die Konsistenz der Daten in der
Datenbank.
Eine Client/Server Datenbank unterscheidet implizite und explizite Transaktionen. Eine
implizite Transaktionen wird bei jedem Ändern, Anfügen oder Löschen einer oder mehrerer
Datenbankzeile (über die SQL-Anweisungen UPDATE, INSERT bzw. DELETE) vom SQL Server
selbst ausgeführt. Wenn Daten geändert, angefügt oder gelöscht werden, verfolgt der SQL
Server diese Änderungen im Transaktionsprotokoll der Datenbank. Dabei werden alle
tatsächlich ausgeführten Operationen aufgezeichnet. Wenn Sie z. B. einen Datensatz ändern,
wird der SQL Server die Originalzeile zwischenspeichern, löschen, ändern, eine neue Zeile
anfügen und alle abhängigen Indizes anpassen. Alle diese Operationen werden im
SQL Server Grundlagen 21
Transaktionsprotokoll aufgezeichnet. Bei einem Fehler innerhalb der Datenänderungen (z. B.
weil der Strom ausgefallen ist), kann der SQL Server beim Neustart die Datenbank „recovern“.
Eine explizite Transaktion startet ein Anwender oder eine Anwendung über die SQLAnweisung BEGIN TRANSACTION. Wenn die Transaktion als erfolgreich gewertet wird, wird
diese mit COMMIT TRANSACTION abgeschlossen. Eine nicht erfolgreiche Transaktion kann mit
ROLLBACK TRANSACTION verworfen werden.
Das klassische Beispiel für eine explizite Transaktion ist die Umbuchung eines Geldbetrags von
einem Konto zum andern. Vor dem Abbuchen des Betrags vom Quellkonto wird die
Transaktion gestartet. Nach dem Abbuchen wird der Betrag dem Zielkonto zugebucht. Nur
wenn weder beim Ab- noch beim Zubuchen ein Fehler aufgetreten ist, wird die Transaktion mit
COMMIT TRANSACTION abgeschlossen. Tritt z. B. beim Zubuchen ein Fehler auf, weil der
Datensatz gerade gesperrt ist, wird die Transaktion mit ROLLBACK TRANSACTION verworfen
und damit auch das Abbuchen erst gar nicht in der Datenquelle gespeichert.
Ein weiteres Beispiel ist eine Anwendung, die in einem Reisebüro das Buchen einer Reise
ermöglicht. Ein Kunde, der eine Reise buchen will, muss zunächst in der Kundentabelle
angelegt werden. Danach wird der Flug in die Flugtabelle und das Hotel in die Hoteltabelle
gebucht. Schließlich wird noch eine Buchung in der Finanzbuchhaltung eingefügt, damit dem
Kunden eine Rechnung gedruckt werden kann. Kurz vor dem Ausdruck der Rechnung
entscheidet sich der Kunde anders und verlässt das Reisebüro. Schön, wenn das Ganze in einer
Transaktion eingeschlossen ist und diese dann einfach verworfen werden kann.
7& ,
5
Transaktionen werden im SQL Server folgendermaßen ausgeführt: Der SQL Server verwaltet
Daten immer auf so genannten Seiten (Pages). Eine Seite besitzt eine Größe von 8 KB, eine
Datenbank ist also im Prinzip eine Sammlung aus 8 KB großen Datenseiten (daneben existieren
noch weitere Seiten, wie z. B. die, auf denen die Indizes verwaltet werden). Eine Datenseite
speichert einen oder mehrere komplette Datensätze, die aufgrund der Seitenarchitektur eine
Größe von maximal 8096 Byte besitzen können (die restlichen Bytes werden für den Seitenkopf
und ein Zeilen-Offset-Array auf der Seite verwendet). Ein Datensatz kann nicht über mehrere
Seiten verwaltet werden. Im Seitenkopf werden u. a. Informationen zur Datenbank, zur
physikalischen Datei der Seite und die Nummer der Seite verwaltet. So kann eine Seite
eindeutig zugeordnet werden. Wenn nun Datensätze geändert, gelöscht oder hinzugefügt
werden, überprüft der SQL Server zunächst, ob die betreffende Seite bereits im Arbeitsspeicher
verwaltet wird. Ist dies nicht der Fall, liest er die Seite ein. Diese Verwaltung der Daten im
Speicher bewirkt nebenbei ein sehr effizientes Caching von Daten: Einmal eingelesene Seiten
müssen beim nächsten Lesen nicht mehr aus der Datei gelesen werden, sondern können dem
wesentlich schnelleren Arbeitsspeicher entnommen werden.
Alle Änderungen werden nun zunächst ausschließlich im Arbeitsspeicher vorgenommen. Die
Datenseite wird dann über ein spezielles Flag als „Dirty“ gekennzeichnet. An diesem Punkt
unterscheiden sich die Daten der Seite im Arbeitsspeicher und in der Datei. Wenn die
Transaktion über COMMIT abgeschlossen oder über ROLLBACK verworfen wird, und die
Änderungen im Arbeitsspeicher abgeschlossen sind, schreibt der SQL Server die Transaktion in
das Transaktionsprotokoll. Dabei speichert der SQL Server einen Datensatz, der den Beginn der
Transaktion kennzeichnet, weitere Datensätze mit den vorherigen und den neuen (geänderten)
Daten und einen Datensatz, der das Ende der Transaktion kennzeichnet (Commit oder Rollback).
Beim Hinzufügen eines Datensatzes speichert das Protokoll den kompletten neuen Datensatz,
beim Löschen den gelöschten und beim Ändern den vorherigen und den neuen (geänderten)
Datensatz. Diese Daten werden jeweils in einem Datenfeld des Protokolls in binärer Form
verwaltet.
Alle Datensätze einer Transaktion werden mit einer eindeutigen Transaktions-ID und einer
aufsteigenden Log Sequenz Nummer (LSN) gekennzeichnet, damit diese Transaktion von
anderen unterschieden und in der korrekten Reihenfolge identifiziert werden kann.
SQL Server Grundlagen 22
Wenn Sie das Ganze einmal life beobachten wollen, fügen Sie einer Tabelle in einer Datenbank
z. B. einen Datensatz hinzu und schauen sich im Query Analyzer dann über
dbcc log (Datenbankname, type=4)
die Einträge im Transaktionsprotokoll an.
&
,#
Die im Arbeitsspeicher geänderten Daten müssen nun noch in die physikalische Datei
geschrieben werden. Dafür läuft im SQL Server ein so genannter Lazywriter-Thread. Dieser
Thread überprüft an so genannten Checkpoints (die per Default einmal pro Minute auftreten), ob
Datenseiten mit dem Dirty-Flag und einer (mit Commit) abgeschlossenen Transaktion existieren
und wie viele Änderungen geschrieben werden müssen. Findet der Thread eine ausreichend
große Menge an Änderungen, beauftragt er einen weiteren Thread (einen Worker-Thread)
damit, alle geänderten Datenseiten in die jeweilige Datei zurückzuschreiben und das Dirty-Flag
zurückzusetzen. Gleichzeitig wird der Beginn des aktiven Teils des Transaktionsprotokolls auf
die LSN gesetzt, die der letzten der geschriebenen LSNs folgt. Die geschriebenen LSNs
verbleiben dann im so genannten wiederherstellbaren Teil des Protokolls (der für BackupStrategien benötigt wird). Nur die LSNs im aktiven Teil werden bei einem Checkpoint
berücksichtigt. Die Frequenz der Checkpoints können Sie als globale Einstellung im SQL
Server anpassen.
,
+ ,
Fällt der SQL Server einmal aus (weil z. B. der Strom ausfällt oder der Rechner abstürzt) wird
beim nächsten Hochfahren automatisch ein Wiederherstell-Prozess gestartet. Dieser Prozess
überprüft den aktiven Teil des Transaktionsprotokolls auf Änderungen, die noch nicht in die
Datenbanken geschrieben wurden. Alle Transaktionen, die mit Commit abgeschlossen sind,
werden dann in die physikalischen Dateien geschrieben. Transaktionen, die gar nicht oder mit
Rollback abgeschlossen sind, werden dabei nicht geschrieben. Damit stellt der SQL Server
sicher, dass abgeschlossene Transaktionen auch komplett geschrieben werden und nicht
abgeschlossene das System nicht in einen inkonsistenten Zustand versetzen können. Alle nicht
abgeschlossenen Transaktionen müssen dann noch einmal nachvollzogen werden.
Alternativ zum automatischen Wiederherstellen können Sie auch ein manuelles
Wiederherstellen ausführen, bei dem Sie den Prozess kontrolliert ausführen können.
5
, #
Transaktionen besitzen ebenfalls eine Bedeutung bei Backup-Strategien. Jede SQL Server
Datenbank sollte regelmäßig gesichert werden. Der SQL Server bietet dazu einen recht einfach
anzuwendenden Mechanismus, der sogar erlaubt, ein automatisches Backup zu bestimmten
Zeiten (über den SQL Server Agent) zu erzeugen. Da ein Backup einer kompletten Datenbank
viel Platz benötigt und die meisten Firmen mehrere Backups verwalten, wird häufig die
Datenbank nur einmal pro Woche gesichert. Jeden Tag wird dann allerdings das
Transaktionsprotokoll gesichert. Wenn die Datenbank beschädigt wird, kann der SQL Server
die kompletten Daten mit Hilfe des letzten Datenbank-Backups und der nachfolgenden
Transaktionsprotokoll-Backups wiederherstellen.
$6
Der Systemkatalog ist aus Tabellen in der Master-Datenbank aufgebaut und speichert u. a. die
Konfiguration des SQL Servers und Informationen über enthaltene Datenbanken. Spezielle
Einstellungen der Datenbanken werden in Systemtabellen innerhalb jeder Datenbank verwaltet.
Die Namen dieser Tabellen beginnen immer mit »sys«.
SQL Server Grundlagen 23
8 0
8
#
$
$ ##
$- $
Wenn der SQL Server nicht automatisch beim Windows-Start gestartet wird, können Sie den
Server mit dem Dienst-Manager interaktiv starten.
Abbildung 12: Der Dienst-Manager des SQL Servers
Mit demselben Programm können Sie den SQL-Server-Dienst und die anderen Dienste des SQL
Servers pausieren und beenden. Daneben können Sie aber auch den Enterprise Manager
verwenden, um den Server zu starten und zu beenden.
Den korrekten Start des Servers können Sie mit dem Query Analyzer überprüfen. Wenn Sie in
Windows als Administrator eingeloggt sind, geben Sie nach dem Start des Query Analyzers im
automatisch erscheinenden Login-Dialog an, dass Sie die Windows-Authentifizierung
verwenden wollen.
Abbildung 13: Login in den SQL Server im Query Analyzer
Wählen Sie dann im Abfragefenster im Feld DB die Datenbank Northwind (eine der
Beispieldatenbanken) aus und geben Sie folgende SQL-Anweisung ein:
SELECT * FROM Products
Grundlegende Operationen 24
Abbildung 14: Abfrage im Query Analyzer
Nach der Ausführung, die Sie über den Schalter mit dem grünen Pfeil oder über F5 starten,
erscheint das Ergebnis im unteren Bereich des Abfrage-Fensters.
8"
#
Mit dem Enterprise Manager verwalten Sie einen oder mehrere SQL Server. Bei der Installation
hat das Installationsprogramm bereits alle im aktuellen Netzwerk erreichbaren SQL Server im
Enterprise Manager registriert. Normalerweise müssen Sie also nichts weiter machen um die im
lokalen Netz verfügbaren SQL Server administrieren zu können. Wenn Sie einen lokalen SQL
Server nachträglich oder einen entfernten SQL Server registrieren müssen, finden Sie Hinweise
dazu im folgenden Abschnitt.
$
+
Um einen SQL Server zu administrieren muss dieser im Enterprise Manager registriert sein. Da
Sie im Enterprise Manager mehrere SQL Server verwalten können, können Sie mehrere
Gruppeneinträge einrichten (per Voreinstellung besteht nur eine Gruppe »SQL SERVERGRUPPE«), um die Übersicht zu gewährleisten.
Wenn Sie einen (lokalen oder entfernten) SQL Server im Enterprise Manager registrieren
wollen, können Sie dies über den Befehl NEUE SQL SERVER REGISTRIERUNG im Kontextmenü
des Gruppeneintrags im Enterprise Manager erledigen. Im erscheinenden, wenig hilfreichen
Assistenten wählen Sie idealerweise die Option, dass Sie die Registrierung ab sofort ohne den
Assistenten ausführen wollen. Im dann erscheinenden Registrierungs-Dialog geben Sie die
Registrationsdaten des SQL Servers an.
Grundlegende Operationen 25
Abbildung 15: Registration eines SQL Servers ohne Assistent
Wählen Sie den Namen des SQL Servers aus der Server-Liste aus oder geben Sie den Namen
ein. (Netz-)lokale SQL Server, die in der Liste nicht auftauchen, können Sie auch über den
Schalter mit den drei Punkten neben der Liste ermitteln.
Für die Registrierung bietet sich immer die Windows-Authentifizierung an wenn Sie als
Administrator eingeloggt sind und wenn der andere SQL Server in derselben Benutzerdomäne
oder in einer Domäne oder auf einem Rechner ausgeführt wird, der ein identisches
Administratorkonto besitzt (wenn der SQL Server also das Administratorkonto kennt). Damit
erreichen Sie, dass Sie sich nicht extra in den SQL Server einloggen müssen um diesen zu
administrieren.
Ist dies nicht möglich, wählen Sie die SQL Server-Authentifizierung. In diesem Fall Sie beim
Login ein gültiges SQL-Server-Administratorkonto (üblicherweise ist das das sa-Konto) mit
dessen Passwort angeben.
Wählen Sie in diesem Fall in einer Produktions-Umgebung auf jeden Fall die
Option BENUTZERNAME UND KENNWORT IMMER ANGEBEN. Damit stellen Sie
sicher, dass ein Benutzer, der den Enterprise Manager gestartet hat, auf jeden Fall
ein gültiges SQL-Server-Administratorkonto und dessen Passwort angeben muss,
um eine Verbindung zum SQL Server aufbauen zu können. Geben Sie stattdessen
bei der Registration ein Benutzerkonto und dessen Passwort fest an, kann jeder
Benutzer ohne weiteres der SQL Server administrieren, da die Login-Daten fest
gespeichert werden.
Nach dem Start des Enterprise Managers können Sie die Objekte der einzelnen SQL Server
hierarchisch auflisten.
Grundlegende Operationen 26
Abbildung 16: Der Enterprise Manager mit drei registrierten SQL Servern (dem lokalen, einer entfernten
SQL-Server- und der lokalen MSDE-Instanz)
Die einzelnen Objekte können Sie hauptsächlich über das Kontextmenü (Rechtsklick auf dem
Objekt) bearbeiten.
Der Enterprise-Manager zeigt standardmäßig neben den benutzerdefinierten
Datenbanken und Datenbank-Objekten auch alle System-Datenbanken und
System-Objekte an. Bei den Datenbanken sind das die Datenbanken master, model,
msdb und tempdb. Bei den Tabellen und Sichten sind das alle, die mit „sys“
beginnen. Da Sie diese in der Praxis eigentlich fast nie (oder nur sehr selten)
benötigen, und besonders die Systemtabellen die Übersicht über eine Datenbank
erschweren, ist es vorteilhaft, wenn Sie die Ansicht der Systemobjekte ausschalten.
Die entsprechende Option finden Sie in den Eigenschaften der Registrierung eines
SQL Servers: Klicken Sie mit der rechten Maustaste auf den Eintrag des SQL
Servers, wählen Sie EIGENSCHAFTEN DER SQL SERVER-REGISTRIERUNG
BEARBEITEN
und schalten Sie in den Eigenschaften die Option
SYSTEMDATENBANKEN UND SYSTEMOBJEKTE ANZEIGEN aus.
Grundlegende Operationen 27
9
9
#
Vor dem Erzeugen, Vergrößern oder Verkleinern einer Datenbank sollten Sie die
Master-Datenbank sichern um das Wiederherstellen des Systems im Fehlerfall zu
erleichtern.
Der Befehl NEUE DATENBANK im Kontextmenü des DATENBANKEN-Ordners öffnet den Dialog
zur Erstellung einer neuen Datenbank.
Abbildung 17: Dialog zum Erzeugen von Datenbanken und Ändern der grundsätzlichen Eigenschaften
der Datenbank
Standardmäßig wird die Datenbankdatei im Unterordner data in dem Ordner erstellt, indem Sie
den SQL Server installiert haben. Per Voreinstellung ist das der Ordner
C:\Programme\Microsoft SQL Server\data. Über die Register DATENDATEIEN und
TRANSAKTIONSPROTOKOLL können Sie jedoch auch jeden anderen Ordner für Dateien der
Datenbank angeben.
Erzeugen und Bearbeiten von Datenbanken 28
Abbildung 18:Einstellung des Speicherorts und der Eigenschaften der Datenbankdatei
Die Einstellung ANFANGSGRÖßE definiert, wie groß die Datenbank bei der Erstellung ist. Ein
MB ist für neue Datenbanken in der Regel ausreichend, wenn Sie die Option DATEI
AUTOMATISCH VERGRÖSSERN eingeschaltet haben. Wenn Sie diese Option jedoch ausschalten,
sollten Sie die Erstellungsgröße auf einen größeren Wert einstellen.
Die Option DATEI AUTOMATISCH VERGRÖSSERN bewirkt, dass der SQL Server die
Datenbankdatei automatisch vergrößert, wenn diese zu einem bestimmten Prozentsatz gefüllt
ist. Damit erreichen Sie, dass der SQL Server nie Schwierigkeiten mit der Größe der Datenbank
bekommt (sofern noch genügend Platz auf der Festplatte verfügbar ist). Sie sollten diese Option
normalerweise nicht abschalten und der Datenbank genügend freien Platz auf den Festplatten
des Systems gönnen. Für diese Option können Sie zusätzlich einstellen, ob die Datei in
festgelegten MB-Einheiten oder prozentual vergrößert wird. Eine Vergrößerung in MB kann
sinnvoll sein, wenn beim Betrieb der Datenbank regelmäßig immer nahezu dieselbe Anzahl an
Datensätzen hinzugefügt wird. Eine Vergrößerung in Prozent bewirkt, dass die Datenbank nach
einer anfänglichen Initialisierungsphase nur noch selten oder gar nicht mehr vergrößert wird.
Diese Option bewirkt in der Regel größere Datenbankdateien als die Vergrößerung in MB.
Bei der Entscheidung der Dateivergrößerungs-Option müssen Sie beachten, dass
das Vergrößern einer Datei recht viel Zeit in Anspruch nimmt. In einem System,
das hoch verfügbar sein muss, sollten Sie deshalb eine möglichst hohe
Anfangsgröße und eben so hohe Dateivergrößerungs-Werte angeben.
Im Feld MAXIMALE DATEIGRÖßE können Sie daneben noch einstellen, ob und wie die
maximale Dateigröße eingeschränkt ist. Mit der Voreinstellung ist die Größe nur auf den
maximal freien Platz auf der Festplatte eingeschränkt.
Erzeugen und Bearbeiten von Datenbanken 29
Der SQL Server ermöglicht die Anlage von Datenbanken in mehreren Dateien. Geben Sie dazu
einfach mehr als einen Dateinamen an. Die erste der angegebenen Dateien ist übrigens die so
genannte primäre Datei.
Die Anlage in mehreren Dateien kann Performancevorteile bringen, wenn die einzelnen Dateien
auf verschiedenen Festplatten angelegt werden und besitzt u. U. Vorteile bei Backup-Strategien
für sehr große Datenbanken.
Beim späteren Anlegen von Tabellen können Sie bei einer aus mehreren Dateien bestehenden
Datenbank entscheiden, in welcher Datei die Tabelle angelegt wird. So können Sie eine
Datenbank unter Umständen so optimieren, dass Tabellen, die häufig gleichzeitig abgefragt
werden (z. B. über Abfragen mit Joins), in verschiedenen Datenbankdateien (und damit
idealerweise auf verschiedenen Festplatten) angelegt werden. Damit nutzen Sie dann die volle
Performance von gleich zwei Festplatten bei Abfragen über diese Tabellen.
Ob eine solche Architektur in der Praxis sinnvoll und Performance-steigernd ist,
kann leider so ohne weiteres nicht beantwortet werden. Im Prinzip hilft nur ein
Ausprobieren. Wenn Sie z. B. bereits ein System einsetzen, das mit schnellen
SCSI-Festplatten auf einem RAID 0, RAID 0+1 oder RAID 5-System arbeitet, und
das mit sehr viel Arbeitsspeicher ausgestattet ist, ist es fraglich, ob eine Aufteilen
der Datenbank auf verschiedene Festplatten überhaupt Sinn macht.
Sinnvoll kann das Aufteilen für spezielle Backup-Strategien sein. Bei einer gesplitteten
Datenbank können Sie die einzelnen Dateien auf mehreren kleineren Festplatten restaurieren
und benötigen nicht unbedingt eine große Festplatte mit ausreichend viel Platz. Im Notfall,
wenn die Datenbank schnell wieder laufen muss, haben Sie vielleicht keine große Festplatte,
aber (evtl. aus den Client-Computern) mehrere kleinere zur Verfügung.
Über der Einstellung DATEIGRUPPE können Sie mehrere Dateien in einzelnen Dateigruppen
anlegen. Mit Dateigruppen können Sie die Performance erhöhen, indem Sie festlegen, in
welchen Dateigruppen (die in der Regel auf verschiedenen Festplatten angelegt werden), die
Systemtabellen und in welchen die verschiedenen Basistabellen und Indizes angelegt werden
(beim Erstellen von Tabellen und Indizes können Sie festlegen, in welcher Dateigruppe diese
angelegt werden). Tabellen und Indizes, auf die häufig zugegriffen wird, können Sie z. B. in
einer Dateigruppe anlegen, deren Dateien auf einer sehr schnellen Festplatte gespeichert sind.
Dateigruppen können zudem Sinn machen, wenn nur Teile der Datenbank über ein Backup
gesichert werden sollen (ein Backup spezieller Dateigruppen). Die ersten angegebenen Dateien
werden immer in der primären Dateigruppen verwaltet. In dieser Dateigruppe werden die
Systemtabellen der Datenbank angelegt. Per Voreinstellung ist die primäre Dateigruppe auch
die Default-Dateigruppe, in der neue Tabellen und Indizes angelegt werden, wenn bei deren
Anlage derselben keine Dateigruppe angegeben wird. Sie können mit der ALTER DATABASEAnweisung eine andere Dateigruppe zur Default-Dateigruppe machen.
5
#
Im Register TRANSAKTIONSPROTOKOLL können Sie die gleichen Einstellungen für das
Transaktionsprotokoll der Datenbank vornehmen, wie für die Datenbank. Das
Transaktionsprotokoll sollte aus Performancegründen auf einer anderen Festplatte angelegt
werden als die Datenbank.
+ ) $6
,
Wenn Sie Festplatten in RAID-Systemen zusammengefasst haben, sollten Sie beachten, dass die
Datenbankdateien auf einem RAID 0 oder RAID 0+1 oder idealerweise auf einem RAID 5-Set
installiert werden sollte. Die in diesen Sets enthaltene parallele Verwendung von mehreren
Platten erhöht die Performance erheblich. Das Transaktionsprotokoll dagegen sollte lediglich
auf einem RAID 1-Set erstellt werden. Aufgrund der sequentiellen Struktur des
Erzeugen und Bearbeiten von Datenbanken 30
Transaktionsprotokolls würde die parallele (und damit aufgeteilte) Speicherung der Daten einen
Performanceverlust mit sich bringen. Ein RAID 1-Set erhöht jedoch auf jeden Fall die
Sicherheit der Daten für den Fall eines Ausfalls einer oder mehrerer Festplatten.
#
Nach der Erstellung der Datenbank können Sie die bei der Erstellung eingestellten Optionen
und weitere Optionen der Datenbank über die Eigenschaften derselben einstellen (über den
Befehl EIGENSCHAFTEN im Kontextmenü der Datenbank).
Abbildung 19: Die Optionen einer Datenbank
Erzeugen und Bearbeiten von Datenbanken 31
Option
ZUGRIFF
EINSCHRÄNKEN
Bedeutung
MITGLIEDER VON 'DB_OWNER', 'DBCREATOR' ODER 'SYSADMIN':
Wenn diese Option eingeschaltet ist können nur der Besitzer der
Datenbank (der Database Owner, der Login, der die Datenbank erstellt
hat), Mitglieder der speziellen Rolle dbcreator (Benutzer, die
Datenbanken erzeugen dürfen) und Mitglieder der Rolls sysadmin
(Systemadministratoren) die Datenbank verwenden. Diese Option
wird oft verwendet, wenn Wartungsarbeiten oder Strukturänderungen
an der Datenbank vorgenommen werden müssen und andere Benutzer
von der Verwendung der Datenbank ausgeschlossen werden sollen. Im
Gegensatz zur Option EINZELBENUTZERMODUS kann der DBO auch
von mehreren unterschiedlichen Computern aus auf die Datenbank
zugreifen.
EINZELBENUTZERMODUS: Mit dieser Option kann nur ein Benutzer
gleichzeitig auf die Datenbank zugreifen. Damit verhindern Sie, dass
andere Benutzer mit der Datenbank arbeiten, während Sie Änderungen
an der Struktur oder an den Optionen vornehmen.
SCHREIBGESCHÜTZT
Diese Option legt fest, dass die Daten grundsätzlich nur gelesen
werden können.
WIEDERHERSTELLUNG - Mit dieser Option definieren Sie, wie der SQL Server das
MODELL
Transaktionsprotokoll bezogen auf Backups verwaltet. Damit legen
Sie fest, bis zu welchem Zeitpunkt eine Datenbank wiederhergestellt
werden kann, nachdem diese z. B. aufgrund eines Stromausfalls
beschädigt wurde.
EINFACH: Das einfache Modell sorgt dafür, dass der SQL Server das
Transaktionsprotokoll bei einem Prüfpunkt abschneidet. Dabei wird
der Speicherplatz der Transaktionen, die bereits in die Datenbank
geschrieben wurden, freigegeben. Da das Transaktionsprotokoll beim
einfachen Modell nur die aktiven Transaktionen beinhaltet, bringt das
Backup dieses Protokolls nichts und wird deswegen auch nicht
ermöglicht. Sie können im einfachen Modell lediglich ein Backup und
Restore der Datenbankdateien (vollständig und differentiell)
ausführen, nicht des Transaktionsprotokolls. Tritt ein Fehler nach
einem Backup auf, sind alle Änderungen zwischen dem Backup und
dem Fehlerzeitpunkt verloren. Das einfache Modell bringt den
»Vorteil«, dass das Transaktionsprotokoll nicht sehr groß werden
kann. Der Nachteil ist, dass Sie erweiterte Backup-Strategien, die das
Transaktionsprotokoll mit einbeziehen, nicht anwenden können.
VOLLSTÄNDIG: Dieses Modell belässt alle Transaktionen im
Transaktionsprotokoll bis dieses oder die Datenbank gesichert wird
(erst dann werden die inaktiven Transaktionen abgeschnitten). Es
ermöglicht damit ein Sichern der Datenbank (vollständig und
differentiell) und ein separates Sichern des Transaktionsprotokolls.
Dieses für die meisten größeren Datenbanken sinnvolle Modell erlaubt
z. B. das Sichern der gesamten Datenbank jeden Tag um 00:00 und
das Sichern des (kleineren und damit schneller gesicherten)
Transaktionsprotokolls in den Betriebspausen. Damit ist die
Wahrscheinlichkeit sehr gering, dass bei einem Crash des Servers
viele Änderungen verloren gehen.
MASSENPROTOKOLLIERT: Dieses dem vollständigen Modell ähnliche
Erzeugen und Bearbeiten von Datenbanken 32
Modell führt dazu, dass bestimmte Massenänderungen an den Daten
(z. B. über SELECT INTO) nur minimal protokolliert werden. Damit
werden diese Massenoperationen zwar performanter ausgeführt und
benötigen weniger Speicherplatz im Transaktionsprotokoll. Beim
einem Crash ist die Gefahr des Datenverlustes bezogen auf die in den
Massenoperationen veränderten Daten aber sehr groß.
ANSI NULL IST
STANDARD
Mit dieser Option können Sie festlegen, ob Tabellenspalten mit der
Einschränkung NULL oder NOT NULL definiert werden wenn bei der
Erzeugung der Spalte weder NULL noch NOT NULL angegeben wird.
REKURSIVE TRIGGER
Normalerweise rufen Änderungen an Daten, die durch einen Trigger
vorgenommen werden, keinen weiteren Trigger auf, der auf den vom
ersten Trigger geänderten Tabellen definiert ist. Wenn Sie diese
Option einschalten, ist der rekursive Aufruf von Triggern möglich. Sie
müssen dabei aufpassen, dass, wenn ein Trigger dieselbe Tabelle
ändert, die den Aufruf des Triggers bewirkt hat, derselbe Trigger
zunächst unendlich oft rekursiv aufgerufen wird (wobei der SQL
Server die Aufrufebenen auf 32 begrenzt).
STATISTIKEN
Statistiken sind Informationen über die Verteilung der Werte von
Spalten in einer Tabelle. Der SQL Server verwendet diese Statistiken
zur Optimierung von komplexen Abfragen (mit Joins). Er erkennt
daraus, welche Tabelle vor welcher anderen abgefragt werden muss,
damit die Abfrage möglichst performant ausgeführt wird. (Spezielle)
Statistiken können Sie von Hand erstellen. Sinnvoll ist aber immer,
dass Sie die Optionen zum automatischen Erstellen und Aktualisieren
eingeschaltet lassen, damit der SQL Server die Default-Statistiken
automatisch erzeugt und aktualisiert. Default-Statistiken werden für
alle Spalten erzeugt, die der WHERE-Klausel einer Abfrage
vorkommen.
AUTOMATISCH
ERSTELLEN
STATISTIKEN
AUTOMATISCH
AKTUALISIEREN
ERKENNUNG VON
ZERISSENEN SEITEN
Wenn Sie diese Option einstellen, erkennt der SQL Server so genannte
zerrissene Seiten. Wie ich bereits erläutert habe, verwaltet der SQL
Server alle Daten auf so genannten Seiten, die jeweils 8 KB groß sind.
Windows verwaltet Daten hingegen normalerweise auf 512-KBSeiten. Wenn der SQL Server eine Seite speichert, muss Windows
diese in mehrere System-Seiten splitten. Der SQL Server nimmt
bereits nach dem Speichern der ersten System-Seite an, dass die
gesamte SQL-Server-Seite erfolgreich gespeichert wurde. Fällt vor
dem Speichern der letzten System-Seite allerdings das System aus, ist
die SQL-Server-Seite nicht komplett gespeichert. Normalerweise
erkennt der SQL Server beim späteren Einlesen der Seite (beim
Recovering) nicht, dass die Seite nun zerrissen ist. Zerrissene Seiten
können die gesamte Datenbank korrumpieren. Lassen Sie diese Option
also eingeschaltet, damit der SQL Server zerrissene Seiten erkennt
und beim Einlesen einen Fehler meldet (der weitere Zerstörungen
verhindert). Das Erkennen zerrissener Seiten kostet lediglich ein
wenig Prozessorzeit, weswegen es nur auf sehr ausgelasteten
Systemen notwendig ist, darauf zu verzichten.
Erzeugen und Bearbeiten von Datenbanken 33
AUTOMATISCH
SCHLIEßEN
AUTOMATISCH
VERKLEINERN
BEZEICHNER IN
ANFÜHRUNGSZEICHEN
VERWENDEN
Mit dieser Option, die nur in der Personal Edition zur Verfügung steht,
können Sie festlegen, dass der SQL Server die Datenbank automatisch
herunterfährt wenn kein Benutzer mehr mit dieser verbunden ist. Da
dann auch der Cache geleert wird, reduzieren Sie den Speicherbedarf
des SQL Servers, was bei einer Verwendung auf einem Desktop-PC
sinnvoll sein kann. Beim erneuten Abfragen dieser Datenbank muss
der Cache allerdings zunächst wieder aufgebaut werden, was dann
recht viel Zeit in Anspruch nimmt.
Bei Datenbanken, bei denen im Betrieb viele Daten gelöscht werden,
macht es u. U. Sinn, diese zu verkleinern. Dieses Verkleinern können
Sie über spezielle SQL-Anweisungen ausführen (DBCC
SHRINKDATABASE oder DBCC SHRINKFILE). Die per Voreinstellung
ausgeschaltete Option AUTOMATISCH VERKLEINERN ermöglicht das
automatische Verkleinern. In diesem Fall überprüft der SQL Server
aber alle 30 Minuten, ob die Datenbank verkleinert werden kann.
Dieses Überprüfen kostet natürlich Zeit und Performance. Lassen Sie
diese Option also ausgeschaltet und verkleinern Sie die Datenbank bei
Bedarf regelmäßig automatisch über einen als SQL-Server-Agent-Job
ausgeführten DBCC-Befehl.
Wenn Sie diese Option einschalten, hält der SQL Server die ANSISQL-Regeln für Anführungszeichen ein. Danach dürfen Zeichenketten
nur in einfache Apostrophe eingeschlossen werden.
Anführungszeichen dürfen dann nur verwendet werden, um
Bezeichner, die Sonder- und Leerzeichen enthalten, einzuschließen
(Beispiel: SELECT "Product Name" FROM "Sale Products"). Ist
diese Option ausgeschaltet, können Sie Anführungszeichen auch für
Zeichenketten verwenden (Beispiel: SELECT * FROM Customers
WHERE City = "Berlin"). Bezeichner mit Sonderzeichen setzen Sie
dann einfach in eckige Klammern.
Tabelle 5: Die Datenbankoptionen
Erzeugen und Bearbeiten von Datenbanken 34
9"
$-
Wenn Sie Datenbanken mit SQL erzeugen wollen, verwenden Sie die CREATE DATABASEAnweisung:
CREATE DATABASE Datenbankname
[ON
[Dateispezifikation [,...n]]
[,Dateigruppe [,...n]]
]
[LOG ON Dateispezifikation [,...n]]
[COLLATE Sortierungsname]
[FOR LOAD | FOR ATTACH]
Mit ON legen Sie fest, in welcher Datei bzw. in welchen Dateien die Datenbank angelegt wird.
Das Argument Dateispezifikation bezieht sich auf die folgenden Angaben, die pro Datei
notwendig sind:
[PRIMARY]
( NAME = Logischer_Dateiname
[, FILENAME = 'Dateiname']
[, SIZE = Größe]
[, MAXSIZE = {Maximale_Größe | UNLIMITED}]
[, FILEGROWTH = Größen_Inkrement])
Wenn Sie mehrere Dateien für eine Datenbank anlegen wollen, müssen Sie eine Datei über
PRIMARY als primäre Datei angeben. Die primäre Datei enthält die Systemtabellen der
Datenbank. Wenn Sie PRIMARY nicht angeben, wird die erste Datei zur primären Datei.
Das Argument Dateigruppe bezieht sich auf Angaben, die für Dateigruppen notwendig sind:
FILEGROUP Dateigruppen_Name Dateispezifikation [,...n]
Für jede Datei müssen sie den physikalischen Dateinamen im Argument FILENAME und den
logischen Dateinamen im Argument NAME angeben. Der logische Dateiname muss nicht
angegeben werden, wenn Sie eine Datenbank mit FOR ATTACH aus bereits vorhandenen Dateien
zusammensetzen. Dieser Dateiname wird in der SQL-Anweisung angegeben, wenn diese sich
auf die Datei bezieht (wie z. B. ALTER DATABASE). Der logische Dateiname muss innerhalb der
Datenbank eindeutig sein.
Das Argument SIZE steuert die Anfangsgröße der Datei. Wird SIZE nicht angegeben,
verwendet der SQL Server für die primäre Datei die Größe der model-Datenbank5 und für alle
weiteren Dateien eine Größe von ein MB. MAXSIZE bestimmt, wie groß die Datei automatisch
wachsen kann. Geben Sie dieses Argument nicht an, oder geben Sie hier UNLIMITED an, kann
die Datei bis zu einer (theoretisch) unendlichen Größe wachsen. Geben Sie den Suffix KB oder
MB an, um die maximale Dateigröße festzulegen.
Das Argument FILEGROWTH bestimmt, wie die Datei vergrößert wird. Sie können hier einen
Wert in KB, MB oder in % angeben. Wenn Sie den Wert 0 angeben, wird die Datei nicht
automatisch vergrößert.
Normalerweise legen Sie eine SQL Server-Datenbank mit einer Anfangsgröße von
einem MB pro Datei an und ermöglichen das automatische Wachsen in %Schritten (z. B. 15%). Dadurch wird gewährleistet, dass die Datenbank nach einer
anfänglichen Initialisierungsphase im späteren Betrieb nicht allzu häufig vergrößert
werden muss. Das automatische Wachsen der Dateien verhindert massive
Probleme, die entstehen, wenn der freie Platz in der Datenbank bzw. im
Transaktionsprotokoll zu klein ist.
5
die model-Datenbank dient beim SQL Server als Vorlage für neu angelegte Datenbanken
Erzeugen und Bearbeiten von Datenbanken 35
Das Argument LOG ON steuert, in welchen Dateien das Transaktionsprotokoll6 der Datenbank
angelegt wird.
Über COLLATE können Sie die Standardsortierung der Datenbank angeben, wenn Sie eine
andere als die Standardsortierung des SQL Servers verwenden wollen (hauptsächlich für
internationale Datenbanken). Sie können hier einen Windows- oder SQL-Sortierungsnamen
angeben. Die entsprechenden Namen sind in der TSQL-Referenz beschrieben. Die
entsprechenden Seiten finden Sie im Inhaltsverzeichnis über INSTALLIEREN VON SQL SERVER /
SORTIERUNGSOPTIONEN FÜR INTERNATIONALE UNTERSTÜTZUNG.
FOR LOAD existiert nur noch aus Kompatibilitätsgründen zum SQL Server 6.5. Mit FOR ATTACH
können Sie eine Datenbank aus bereits vorhandenen Dateien aufbauen. Dieses Argument
benötigen Sie immer dann, wenn Sie Datenbanken mit mehr als 16 Dateien aufbauen wollen, da
CREATE DATABASE in einem Schritt nur maximal 16 Dateien zulässt.
Im einfachsten Fall (ohne eine Datenbank in mehrere Dateien aufzusplitten), sieht die SQLAnweisung z. B. folgendermaßen aus:
CREATE DATABASE Test
ON
( NAME=Test_Data,
FILENAME='c:\Data\Test_Data.mdf',
SIZE=10MB,
FILEGROWTH=20%)
LOG ON
( NAME=Test_Log,
FILENAME='c:\Logs\Test_Log.ldf',
SIZE=1MB,
FILEGROWTH=10%)
Wenn die Datenbank in mehrere Dateien aufgesplittet werden soll, sieht die SQL-Anweisung z.
B. folgendermaßen aus:
CREATE DATABASE Test
ON PRIMARY
( NAME=Test_Data_1,
FILENAME='c:\Data\Test_Data_1.mdf',
SIZE=10MB,
FILEGROWTH=20%),
( NAME=Test_Data_2,
FILENAME='d:\Data\Test_Data_2.mdf',
SIZE=10MB,
FILEGROWTH=20%)
LOG ON
( NAME=Test_Log,
FILENAME='e:\Logs\Test_Log.ldf',
SIZE=1MB,
FILEGROWTH=10%)
Durch das Schlüsselwort PRIMARY wird die erste Datenbankdatei als die primäre Datei
definiert.
Die Anweisung kann noch komplexer werden, wenn Sie Datenbankdateien in Dateigruppen
anlegen. Für entsprechende Beispiele verweise ich auf die TSQL-Hilfe zur CREATE DATABASEAnweisung.
6
Das Transaktionsprotokoll wird im Skript „Microsoft SQL-Server“ erläutert.
Erzeugen und Bearbeiten von Datenbanken 36
:
* %
:
5
5
#
Mit dem Enterprise Manager ist das Erstellen von Tabellen in einer Datenbank sehr einfach.
Wählen Sie dazu den Befehl NEUE TABELLE im Kontextmenü des TABELLEN-Ordners im
Ordner der Datenbank. Nachdem Sie den Namen der neuen Tabelle eingegeben haben, erscheint
der Dialog zur Einrichtung der Tabelle.
Abbildung 20: Dialog zum Einrichten von Tabellen
Geben Sie idealerweise einen Spaltennamen an, der der SQL-Konvention entspricht (nur
Buchstaben, Zahlen, der Unterstrich, # und &; das erste Zeichen muss ein Buchstabe sein). Im
SQL Server können Sie aber auch Spaltennamen verwenden, die Sonderzeichen (Leerzeichen,
Bindestriche etc.) enthalten. Abgesehen davon, dass Sie diese Bezeichner später in Abfragen in
eckigen Klammern angeben müssen, führen solche Bezeichner bei eventuellen Übertragungen
einer SQL-Server-Datenbank in andere Datenbanksysteme (z. B. Oracle), die Sonderzeichen
nicht erlauben, zu Problemen.
Daneben können Sie einstellen, ob Null-Werte in der Spalte erlaubt sind oder nicht. Nur
Spalten, die keine Nullwerte enthalten dürfen, können als Primärschlüssel definiert werden.
Beachten Sie, dass der Umgang mit NULL-Werten in Client-Anwendungen häufig einen großen
Aufwand erfordert, da diese für Spalten, die NULL-Werte erlauben vor dem Lesen immer zuerst
abfragen muss, ob die Spalten NULL enthält. Verwenden Sie die Option NULL ZULASSEN also
mit Bedacht.
In der Option STANDARDWERT geben Sie einen Wert ein, der standardmäßig für neue
Datensätze in dieses Datenfeld geschrieben werden soll.
Erzeugen und Verwalten von Tabellen 37
:
6#
Bei der Definition von Spalten können Sie die folgenden Datentypen verwenden:
Datentyp
Größe
(Byte)
Beschreibung
char[(n)]
0-8000
ASCII-Zeichenketten festgelegter Größe. In char-Spalten,
die keine Null-Werte erlauben, werden Zeichenketten nach
rechts mit Leerzeichen aufgefüllt, die u. U. bei der
Bearbeitung abgeschnitten werden müssen. Werden
Zeichenketten eingegeben, die größer sind als der
Maximalwert, so schneidet der Server die Zeichen nach
rechts einfach ab. Sie können bis zu 8000 Zeichen in
diesem Datentyp speichern.
nchar[(n)]
0-8000
nchar wird wie char verwendet, speichert jedoch
varchar[(n)]
0-8000
varchar speichert wie char ASCII-Zeichenketten. Für
varchar-Zeichenketten geben Sie zwar auch die
Unicode-Zeichen, weswegen nur 4000 Zeichen möglich
sind.
Maximalgröße an, der Server speichert jedoch nur die
tatsächlich eingegebenen Zeichen. Werden Zeichenketten
eingegeben, die größer sind als der Maximalwert, so
schneidet der Server die Zeichen nach rechts ab.
nvarchar[(n)]
0-8000
nvarchar wird wie varchar verwendet, speichert jedoch
datetime
8
Datumswerte zwischen dem 1.1.1753 und dem 31.12.9999.
Wenn bei der Eingabe die Zeit weggelassen wird, wird der
Wert 00:00:00 verwendet, wird das Datum weggelassen,
wird der 01.01.1900 eingetragen.
smalldatetime
4
Speichert Datumswerte zwischen dem 01.01.1900 und dem
06.06.2079 mit einer Genauigkeit von einer Minute. Wenn
Sie erreichen wollen, dass Ihre Software noch nach dem
06.06.2079 korrekt läuft, verwenden Sie diesen Datentyp
besser nicht (denken Sie an das Jahr 2000-Problem).
bigint
8
Ganze Zahlen zwischen -263 (-9.223.372.036.854.775.808)
und 263-1 (9.223.372.036.854.775.807)
int
4
Ganze
Zahlen
+2.147.483.647
smallint
2
Ganze Zahlen zwischen -32.768 bis +32.767
tinyint
1
Ganze Zahlen zwischen 0 und 255
Unicode-Zeichen.
zwischen
-2.147.483.648
und
Erzeugen und Verwalten von Tabellen 38
decimal[(p [, s])]
numeric[(p [, s])]
1-17 je nach Zahlen mit fester Dezimalstelle zwischen -1038 und 1038-1
Genauigkeit mit einer Genauigkeit von 1 bis 38 Ziffern. p (Precision)
gibt an, wie viele Ziffern links und rechts vom Komma
insgesamt gespeichert werden können, s (Scale) gibt die
Anzahl der Ziffern rechts vom Komma an. s und muss ein
Wert zwischen 0 und p sein. Wenn Sie s nicht angeben,
verwendet der SQL Server den Wert 0; für p wird
standardmäßig 16 eingesetzt. SQL/92 definiert zwar einen
Unterschied zwischen decimal und numeric (bei
decimal müssen mindestens s Dezimalstellen vorhanden
sein, bei numeric muss die Anzahl der angegebenen
Dezimalstellen genau sein), der SQL Server macht
dagegen keinen Unterschied.
float[(n)]
8
Zahlen mit fließender Dezimalstelle. n gibt die Genauigkeit
mit einem Wert von 1 bis 53 an. Geben Sie eine
Genauigkeit von 24 an, so besitzt dieser Typ dieselbe
Bedeutung wie real. Standardmäßig wird eine
Genauigkeit von 15 verwendet. Damit können Zahlen
zwischen -1.79 * 10308 und 1.79 * 10308 gespeichert
werden. Bei einer Genauigkeit von 1-24 werden sieben
Dezimalstellen verwaltet, bei einer Genauigkeit von 25 bis
53 dagegen 15.
real
4
real steht im SQL Server für float(24).
money
8
Dezimalzahl mit vier festen Dezimalstellen zwischen 922.337.203.685.477,5808
und
+922.337.203.685.477,5807. money wird für Währungen
verwendet, da diese üblicherweise mit vier Dezimalstellen
gerechnet werden. Berechnungen mit festen Dezimalstellen
sind schneller als solche mit dynamischen und vermeiden
Rundungsfehler, die durch die eingeschränkte Genauigkeit
der anderen Datentypen entstehen.
smallmoney
4
Währungsbeträge
+214.748,3647
text
n Seiten zu Dynamische Zeichenketten bis 2.147.483.647 Zeichen
je 8 KB
ntext
n Seiten zu ntext speichert wie text dynamische Zeichenketten,
je 8 KB
allerdings als Unicode-Zeichen. Deswegen können auch
nur 1.073.741.823 Zeichen gespeichert werden.
image
n Seiten zu image speichert binäre Daten (Dateien, Objekte) bis zu
je 8 KB
2.147.483.647 Byte Größe. image wird häufig zur
Speicherung von binären Objekten, wie z. B. MicrosoftWord-Dokumenten verwendet.
binary
0-8000
Dieser Datentyp speichert binäre Daten mit einer
maximalen Länge von 8000 Byte.
varbinary
0-8000
varbinary speichert wie binary binäre Daten. Der
zwischen
-214.748,3648
und
Server verwaltet jedoch nur soviel Speicherplatz, wie die
tatsächlich eingegebenen Daten benötigen, und nicht wie
bei binary immer die eingestellte Größe.
Erzeugen und Verwalten von Tabellen 39
1
bit speichert boolesche Werte in Form von 0 oder 1.
timestamp
8
Ein timestamp-Feld wird bei jedem Hinzufügen oder
Ändern eines Datensatzes automatisch mit einem über die
gesamte Tabelle eindeutigen Wert (der aus der Systemzeit
generiert wird) belegt. Solche Felder benötigen Sie immer
dann (und eigentlich auch nur dann), wenn Tabellen in
mehreren Datenbanken repliziert werden sollen. Der SQL
Server erkennt beim Synchronisieren der einzelnen
Datenbanken am timestamp-Feld, ob ein Datensatz
verändert wurde. Die Speicherung entspricht der eines
varbinary(8)-Feldes. Sie können nur ein timestampFeld pro Tabelle generieren.
uniqueidentifier
16
Dieser Datentyp dient der Speicherung einer GUID
(Global Unique Identifier). Eine GUID ist ein 16-Bit
Hexadezimalwert, der über die gesamte Welt eindeutig ist.
In TSQL kann eine GUID mit der NEWID-Funktion
erzeugt werden. GUIDs werden häufig zur Benennung und
Identifikation von Objekten verwendet.
sysname
256
sysname ist ein benutzerdefinierter Datentyp, der als
nvarchar(128) definiert ist. Nullwerte werden nicht
bit
Integerwerte können eingegeben werden, werden jedoch
als 1 gewertet.
erlaubt. Dieser Datentyp wird vom SQL Server in
Systemtabellen verwendet.
cursor
Dieser Datentyp verweist auf einen Cursor. Ein Cursor
wird eigentlich nur innerhalb von Stored Procedures,
Triggern und Funktionen eingesetzt, um eine Tabelle oder
Abfrage sequenziell durchlaufen zu können (was nur selten
notwendig ist).
table
Dieser Datentyp wird hauptsächlich innerhalb von Stored
Procedures verwendet, um das Ergebnis einer Abfrage
temporär zwischenzuspeichern (ähnlich einem Recordset
bei ADO oder einem ResultSet bei JDBC).
sql_variant
Dieser Datentyp ermöglicht das Speichern verschiedener
Datentypen in einem Feld, ähnlich dem Datentyp Variant
in Visual Basic.
Tabelle 6: Die Datentypen des SQL Servers
:
"
4 ,
)
6&
Der Primärschlüssel einer Tabelle wird über einen Primary Key Constraint (eine
Primärschlüssel-Einschränkung) definiert und dient der eindeutigen Identifizierung einzelner
Datensätze und der Herstellung von Beziehung zwischen Tabellen. Ein Primärschlüssel besteht
in der Regel aus einer Spalte, kann jedoch auch aus mehreren Spalten zusammengesetzt sein.
Die in die betreffenden Felder eingegebenen Daten müssen über die gesamte Tabelle eindeutig
sein.
Wenn Sie der Tabelle einen Primärschlüssel hinzufügen wollen, markieren Sie die Felder, die
den Primärschlüssel definieren (durch einen Klick auf das graue Kästchen links, wenn Sie
mehrere Spalten markieren wollen, halten Sie die STRG-Taste beim Klicken gedrückt) und
betätigen das Schlüssel-Symbol in der Symbolleiste. Für einen Primary Key Constraint erzeugt
Erzeugen und Verwalten von Tabellen 40
der SQL Server intern einen eindeutigen (Unique-) Index. Die Spalten des Primärschlüssel
brauchen (und sollten7) Sie also nicht explizit mit einem Index versehen, um die Suche oder das
Sortieren in diesen Spalten zu beschleunigen.
Per Default wird der Index des Primärschlüssels als Clustered Index (gruppierter Index) erstellt.
Wenn in Abfragen die Felder eines gruppierten Index in WHERE-, ORDER BY-, oder GROUP BYKlauseln verwendet werden, werden diese Abfragen wesentlich schneller ausgeführt, als wenn
der Index nicht gruppiert ist. Das liegt daran, dass ein gruppierter Index nicht ein Index im
klassischen Sinn ist, sondern dafür sorgt, dass die Datenseiten der Tabelle in einem balancierten
Baum (B-Baum) gespeichert werden, dessen Schlüssel die im Index enthaltenen Spalten sind.
Bei klassischen Indizes werden in einem B-Baum lediglich die Datensatznummern der
Datensätze gespeichert.
Eine Tabelle kann nur einen gruppierten Index enthalten und sollte, wenn Spalten
indiziert sind, aus Performancegründen immer einen gruppierten Index enthalten.
Sie können, wenn Sie einen anderen Index als gruppierten Index verwenden wollen, auch die
Clustered-Option für den Index des Primärschlüssels abschalten.
Eine Identitätsspalte (Identity-Column) ist eine Spalte, die einen numerischen Datentyp besitzen
muss und vom Server bei jedem neuen Datensatz um einen einzustellenden Wert inkrementiert
wird. Sie können für die Identitätsspalte nur Spalten auswählen, die numerisch sind, keine
Nullwerte zulassen und keinen Defaultwert besitzen. Die Identitätsspalte kann mit der Spalte für
den Primärschlüssel identisch sein. Der Eintrag in der Option ID-STARTWERT spezifiziert den
Anfangswert für neue Datensätze. ID-SCHRITTWEITE definiert den Wert mit dem für jeden
neuen Datensatz inkrementiert wird.
:
/
+ %0;)
Die Option IST ROWGUID besagt, dass die Spalte eine Spalte ist, die einen GUID8-Wert
speichern soll, der einen Datensatz ein-eindeutig identifizieren soll. GUID-Werte sind
hexadezimale Werte (wie z. B. der Wert BA2DE025-8467-11D3-9E43-00400548C419), die per
„intelligentem“ Zufallsgenerator mit Hilfe des aktuellen Datums, der Zeit, der ID der
Netzwerkkarte und aktuellen Registerinhalten erzeugt werden und die über die gesamte Welt
(bzw. über das gesamte Universum) eindeutig sind. GUIDs werden üblicherweise zur
Identifizierung gespeicherter Objekte verwendet. Mit GUIDs können Sie auch viele Probleme
umgehen, die bei Identitätsspalten auftreten können, wenn mehrere Benutzer gleichzeitig neuen
Datensätze anlegen. Der SQL Server nutzt GUID-Spalten außerdem bei Replikationen.
Eine GUID-Spalte muss den Datentyp uniqueidentifier besitzen und sollte als Defaultwert
die Funktion NEWID() zugewiesen bekommen, die einen neuen GUID-Wert erzeugt.
:
8
)
; <
&
Indizes beschleunigen Abfragen, wenn die im Index enthaltenen Felder in WHERE-, ORDER BY-,
oder GROUP BY-Klauseln verwendet werden oder wenn mit anderen Techniken (z. B. mit der
Find-Methode in ADO) in diesen Spalten suchen. Ein Index wird in einem balancierten Baum
gespeichert. Der SQL Server speichert für normale (keine Clustered-) Indizes für jeden
Datensatz ein Blatt im Baum mit dem/den Schlüsselwert(en) und einem Verweis auf den
7
Wenn Sie die Spalten eines Primärschlüssels mit einem zusätzlichen Index versehen, muss dieser Index
bei Aktualisierungen der Tabelle ebenfalls aktualisiert werden, was die Aktualisierung unnötig
verlangsamt.
8
Global Unique Identifier
Erzeugen und Verwalten von Tabellen 41
Datensatz. Die Suche in einem balancierten Baum ist wesentlich schneller als die sequentielle
Suche in den Datensätzen, die ohne Index notwendig ist.
Indizes erzeugen Sie über die Eigenschaften der Tabelle, die über das erste Symbol von rechts
in der Symbolleiste erreichbar ist. Wählen Sie das Register INDIZES / SCHLÜSSEL.
Abbildung 21: Register zur Definition von Indizes in den Tabelleneigenschaften mit einem auf den
Nachnamen des Kunden gesetzten Index
Wählen Sie den Schalter NEU um einen neuen Index zu erstellen. Geben Sie danach im Feld
INDEXNAME einen sinnvollen Namen für den neuen Index an und wählen Sie die Spalten, die im
Index verwaltet werden sollen.
Erzeugen und Verwalten von Tabellen 42
Das korrekte Erstellen von Indizes ist keine einfache Aufgabe. Indizieren Sie
zunächst nur die Felder, die später häufiger in WHERE- ORDER BY- oder GROUP
BY-Klauseln verwendet werden. Zusätzlich sollten Sie normalerweise auch die
Felder indizieren, die mit den Primärschlüsselfeldern anderer Tabellen in
Beziehung gesetzt und die in Abfragen häufiger über Joins mit diesen in Beziehung
gesetzt werden sollen. Setzen Sie jedoch nicht zu viele Indizes, da diese bei jedem
Hinzufügen, Ändern oder Löschen von Daten aktualisiert werden müssen, was u.
U. recht viel Zeit in Anspruch nehmen kann. Zusammengesetzte Indizes machen
dann Sinn, wenn später häufiger mehrere Spalten der Tabelle in einer definierten
Reihenfolge in WHERE- ORDER BY- oder GROUP BY-Klauseln verwendet werden.
Wichtig zu wissen dabei ist, dass der SQL Server immer auch die erste Spalte eines
zusammengesetzten Index als normale Indexspalte verwenden kann um Abfragen
zu optimieren, die sich nur auf diese Spalte beziehen. Eine sehr gute Hilfe beim
Ermitteln der optimalen Indizes der Enterprise-Manager-Indexoptimierer, den ich
in diesem Artikel allerdings nicht beschreibe.
; <
)
&
'
, 4
(
; <
Ein Unique Constraint und ein Unique Index ähnelt einem Primärschlüssel: die betreffenden
Felder sind eindeutig indiziert und erlauben damit keine doppelten Werte. Unique
Constraints/Indizes werden dazu verwendet, die Datenintegrität zu wahren und Beziehungen
zwischen Tabellen herzustellen wenn der Primärschlüssel dafür nicht geeignet ist bzw. nicht
vorhanden ist oder bereits verwendet wird.
Der Unterschied zwischen einem Unique Constraint und einem Unique Index ist mir nicht klar
geworden, da ein Unique Constraint genau wie ein Unique Index (wohl aber intern) indiziert ist
und damit auch immer einen Performancegewinn bei Verwendung der betroffenen Felder in
WHERE-, ORDER BY-, oder GROUP BY-Klauseln bringt. Möglicherweise hängt die Möglichkeit,
einen Unique Constraint zu erzeugen mit der Tatsache zusammen, dass der derzeit gültige SQLStandard (SQL/92) keine Indizes kennt.
Um einen Unique Constraint zu erstellen, wählen Sie die Option UNIQUE ERSTELLEN und
EINSCHRÄNKUNG. Wollen Sie einen Unique Index erstellen, wählen Sie statt EINSCHRÄNKUNG
eben INDEX.
Die Option DOPPELTE SCHLÜSSEL IGNORIEREN gilt nur für eindeutige, gruppierte Indizes und
steuert das Verhalten des SQL Servers beim Versuch, einen Datensatz mit einem Wert in der
indizierten Spalte anzufügen, der bereits existiert. Schalten Sie diese Option ein, generiert der
SQL Server beim Anfügen von Datensätzen mit doppelten Werten nur eine Warnmeldung, fügt
diese Datensätze nicht an, führt jedoch die SQL-Anweisung weiter aus. Schalten Sie die Option
ab, wird beim Anfügen solcher Datensätze ein Fehler generiert und die komplette SQLAnweisung zurückgesetzt.
Erzeugen und Verwalten von Tabellen 43
Das folgende Beispiel erzeugt eine Tabelle mit einem eindeutigen gruppierten Index, der
doppelte Schlüssel ignorieren soll (mit SQL ):
/* Erstellen einer Tabelle, die die Werte speichern soll, die
an die Testtabelle angefügt werden sollen */
CREATE TABLE Test_Values (Value int)
/* Einfügen
INSERT INTO
INSERT INTO
INSERT INTO
der Testwerte */
Test_Values VALUES (10)
Test_Values VALUES (11)
Test_Values VALUES (10)
/* Erstellen der Test-Tabelle */
CREATE TABLE Dup_Key_Test (
ID int IDENTITY,
No_Dup_Key int )
/* Erstellen des gruppierten, eindeutigen Index auf der Test-Tabelle */
CREATE UNIQUE CLUSTERED INDEX IX_Dup_Key_Test
ON Dup_Key_Test (No_Dup_Key)
WITH IGNORE_DUP_KEY
/* Einfügen doppelter Spalten */
INSERT INTO Dup_Key_Test (No_Dup_Key) SELECT Value FROM Test_Values
Das Einfügen der Datensätze mit doppelten Werten führt in diesem Beispiel dazu, dass der SQL
Server zwar die zwei eindeutigen Datensätze anfügt, für den doppelten Datensatz jedoch eine
Warnmeldung ausgibt:
Server: Nachr.-Nr. 3604, Schweregrad 16, Status 1, Zeile 20
Doppelter Schlüssel wurde ignoriert.
Die Tabelle hat nach Ausführung dieses Beispiels die folgenden Datensätze gespeichert:
ID
----------1
2
No_Dup_Key
----------10
11
(2 row(s) affected)
Wenn Sie die Option IGNORE_DUP_KEY nicht angeben, wird bei dem Beispiel kein Datensatz
angefügt:
Server: Nachr.-Nr. 2601, Schweregrad 14, Status 3, Zeile 19
Zeile mit doppeltem Schlüssel kann in Objekt 'Dup_Key_Test' mit eindeutigem
Index 'IX_Dup_Key_Test' nicht eingefügt werden.
Die Anweisung wurde beendet.
2
Ein Index wird genau wie die Daten physikalisch auf Seiten von acht KB Größe gespeichert.
Mit dem Füllfaktor können Sie bestimmen, wie viel Platz auf diesen Seiten bei der
Neuorganisation der Seiten und beim ersten Erstellen des Index frei bleibt (ein Füllfaktor von
75% bewirkt, dass 25% frei bleiben). Ist der Füllfaktor auf 0 eingestellt, wird der DefaultFüllfaktor der Datenbank verwendet.
Bei Änderungen der indizierten Spalten der Datensätze oder beim Anfügen von neuen
Datensätzen muss immer auch der Index angepasst werden. Ist der Füllfaktor 100%, müssen
dann u. U. einige oder auch alle Indexseiten umorganisiert werden, was natürlich recht viel Zeit
kosten kann. Mit einem niedrigen Füllfaktor können Sie das Umorganisieren in den meisten
Fällen vermeiden, da die Indexseiten ja noch Platz für neue Einträge besitzen. Ein niedriger
Füllfaktor bewirkt allerdings auch, dass mehr Indexseiten vorhanden sind, was den benötigten
Speicherplatz erhöht und zudem (was wesentlich wichtiger ist) die Performance bei Abfragen
vermindert. Die korrekte Einstellung des Füllfaktors ist eine schwierige Feintuning-Arbeit und
muss u. U. mit mehreren Tests ermittelt werden. Als Faustregel gilt: Ist die Anwendung
Erzeugen und Verwalten von Tabellen 44
bezogen auf die betroffene Tabelle abfrageintensiv, sollte der Füllfaktor größer sein, ist die
Anwendung transaktionsintensiv (viele Änderungen und Hinzufügen von Datensätzen), sollte
der Füllfaktor kleiner sein.
&
)
'
##
)
(
Wenn in Abfragen die Felder eines gruppierten Index in WHERE-, ORDER BY-, oder GROUP BYKlauseln verwendet werden, werden diese Abfragen wesentlich schneller ausgeführt, als wenn
der Index nicht gruppiert ist. Das liegt daran, dass ein gruppierter Index nicht ein Index im
klassischen Sinn ist, sondern dafür sorgt, dass die Datenseiten der Tabelle in einem balancierten
binären Baum (B-Baum) gespeichert werden, dessen Schlüssel die im Index enthaltenen Spalten
sind. Bei klassischen Indizes werden in einem B-Baum lediglich die Datensatznummern der
Datensätze gespeichert.
Eine Tabelle kann nur einen gruppierten Index enthalten und sollte, wenn Spalten indiziert sind,
aus Performancegründen immer einen gruppierten Index enthalten.
Beachten Sie, dass per Default der Primärschlüssel aus einem gruppierten Index besteht. Sie
können, wenn Sie einen anderen Index als gruppierten Index verwenden wollen, auch die
Clustered-Option für den Index des Primärschlüssels abschalten.
Die Option DOPPELTE SCHLÜSSEL IGNORIEREN ist nur relevant für nicht eindeutige Indizes.
Wenn Sie diese Option einschalten, werden (lt. Delaney) Änderungen an den Daten, die
mehrere Datensätze in der Tabelle betreffen, nicht komplett verworfen, wenn die Änderung
eines Datensatzes einen doppelten Wert in der indizierten Spalte verursachen würde. Diese
Änderungen werden dann einfach ignoriert. Normalerweise ist diese Option ausgeschaltet,
womit die komplette SQL-Anweisung beim Auftreten eines Indexfehlers verworfen wird.
Eine Tabelle ist z. B. folgendermaßen aufgebaut:
ID
Eindeutige_Spalte
1
a
2
b
3
c
4
d
Ist die Eindeutige_Spalte eindeutig indiziert, führt die SQL Anweisung
UPDATE Test SET Eindeutige_Spalte = 'x' WHERE ID IN (1, 2)
bei ausgeschalteter Option zu einem Fehler, die Änderung wird nicht vorgenommen. Ist die
Option eingeschaltet, sollte eigentlich der erste Datensatz aktualisiert und die Änderung beim
zweiten Datensatz ignoriert werden. Leider funktionierte dies bei einem Test (wie so oft) auf
meinem System nicht, der SQL Server ignorierte diese Option einfach. Die Hilfe zum SQL
Server sagt leider zu dieser Option sehr wenig und nach meiner Meinung auch falsches aus.
Die Option STATISTIKEN NICHT AUTOMATISCH NEU BERECHNEN bewirkt, dass die für
Optimierungen intern verwendete Indexstatistik nicht neu berechnet werden soll. Diese Option
sollten Sie nicht einschalten, da Sie damit die automatische Optimierung von Abfragen
verschlechtern.
&
,
, 4
Eine Check-Einschränkung (Check Constraint) ist eine Bedingung, die überprüft wird, wenn
Datensätze der Tabelle geändert oder angefügt werden. Eine Check-Einschränkung könnte z. B.
festlegen, dass die Kunden-Nummer nicht negativ sein darf. Bei Verletzungen der so definierten
Regel wird der Datensatz nicht geändert bzw. angefügt und ein Fehler generiert.
Erzeugen und Verwalten von Tabellen 45
Check-Einschränkungen können Sie lokal (nur innerhalb der Tabelle gültig) oder global (in
allen Tabellen anwendbar) definieren. Lokale Check-Einschränkungen werden über das
Register CHECK-EINSCHRÄNKUNGEN in den Tabelleneigenschaften erstellt, wobei Sie die
SQL-Syntax für Bedingungen verwenden. Wählen Sie den Schalter NEU, um eine neue CheckEinschränkung zu erstellen.
Abbildung 22: Register zur Definition von Check-Einschränkungen mit einer die Kunden-Nummer
überprüfenden Einschränkung
Die Check-Einschränkung erhält einen Bezeichner der per Konvention mit CK_ beginnen sollte.
Verwenden Sie Ihnen selbst zuliebe Bezeichner, die einer bestimmten Konvention folgen, z. B.
CK_ mit angehangenen Tabellen- und Feldnamen. Dies erleichtert Ihnen später die
Fehlerauswertung in der Client-Anwendung, da Sie Fehler wie
Server: Nachr.-Nr. 547, Schweregrad 16, Status 1, Zeile 1
Die INSERT-Anweisung verstieß gegen die COLUMN CHECK-Einschränkung
'CK_Kunden_Kunden_Nr'. Der Konflikt trat in der Fahrradverleih-Datenbank,
Tabelle 'Kunden', column 'Kunden_Nr' auf.
Die Anweisung wurde beendet.
erhalten, die Sie für den Anwender erst noch übersetzen müssen. Wenn Sie dann nach „CK_“
suchen können, um den Feldnamen zu ermitteln, werden Sie sich freuen9.
Eine Einschränkung kann sich auch auf mehrere Spalten beziehen.
9
Theoretisch könnten Sie auch im Fehlertext nach den '-Zeichen suchen, um den Spaltennamen zu
erhalten. Ich würde mich jedoch nicht darauf verlasen, dass der Spaltenname in den verschiedenen
Sprachen und den zu erwartenden neuen Versionen des SQL Servers immer an derselben Stelle steht.
Erzeugen und Verwalten von Tabellen 46
Wenn Sie die Option EINSCHRÄNKUNG FÜR INSERT UND UPDATE ERZWINGEN ausschalten,
wird die Einschränkung inaktiv. Diese Möglichkeit ist in Sonderfällen sinnvoll, nämlich dann,
wenn Sie externe Daten importieren, die u. U. den definierten Regeln nicht entsprechen. Durch
das Ausschalten der Einschränkungen können Sie die Daten importieren, danach in einen
konsistenten Zustand versetzen (indem Sie die fehlerhaften Daten korrigieren) und schließlich
wieder die Einschränkung aktivieren.
Vorhandene Einschränkungen können Sie über die Liste anzeigen, bearbeiten und auch wieder
über den LÖSCHEN-Schalter löschen.
0
&
,
, 4
Globale Check-Einschränkungen können Sie an Spalten in mehreren Tabellen binden und
erleichtern sich somit die Pflege und Wartung global verwendbarer Regeln. Globale CheckEinschränkungen erstellen Sie im Enterprise-Manager über den Ordner REGELN im
betreffenden Datenbankordner. Wählen Sie im Kontextmenü den Befehl NEUE REGEL.
Abbildung 23: Der Dialog zur Einrichtung von globalen Regeln mit einer Regel, die eine Postleitzahl
überprüfen soll
Der Name beginnt wieder mit CK_. In der Einschränkung dürfen Sie keinen Spaltennamen
verwenden, da die Einschränkung an beliebige Spalten gebunden werden kann. Verwenden Sie
stattdessen Variablen, die Sie am Präfix @ erkennen.
Über den Schalter SPALTEN BINDEN (der erst verfügbar ist, nachdem Sie die Regel gespeichert
haben) wird die globale Einschränkung an Spalten aus verschiedenen Tabellen gebunden.
Erzeugen und Verwalten von Tabellen 47
Abbildung 24: Der Dialog zur Binden von Regeln an Tabellenspalten
Wenn ein eingegebener Wert den Einschränkungen nicht entspricht, lässt der SQL Server keine
Änderung bzw. kein Anhängen von Datensätzen zu und erzeugt einen Fehler. Die folgende
SQL-Anweisung:
INSERT INTO Kunden (Kunden_Nr, Vorname, Nachname, Strasse, Plz, Ort, Telefon)
VALUES (1001, 'Zaphod', 'Beeblebrox', 'Starway 1', 'X-1', 'Milchstrasse', '012345')
erzeugt z. B. diesen Fehler:
Server: Nachr.-Nr. 513, Schweregrad 16, Status 1, Zeile 1
Beim Einfügen oder Aktualisieren einer Spalte trat ein Konflikt mit einer
Regel auf, die in einer vorherigen CREATE RULE-Anweisung festgelegt wurde.
Die Anweisung wurde beendet. Der Konflikt trat in der FahrradverleihDatenbank, Kunden-Tabelle, Plz-Spalte auf.
Die Anweisung wurde beendet.
Erzeugen und Verwalten von Tabellen 48
:"
% ,
)
5
4
Wenn Sie zwischen Tabellen Beziehungen mit referentieller Integrität aufbauen wollen, können
Sie prinzipiell zwischen zwei Varianten wählen:
• Verwendung von DRI (Declared Referential Integrity),
•
Verwenden von Triggern.
DRI verwenden Sie, wenn Sie in der Detailtabelle einen Fremdschlüssel (Foreign Key)
aufbauen, der den Primärschlüssel oder ein mit einem Unique-Index indiziertes Feld der
Mastertabelle referenziert. DRI besitzt gegenüber der Verwendung von Triggern mittlerweile
nur noch Vorteile. Trigger waren in Vorversionen des SQL Servers notwendig um Beziehungen
mit kaskadierenden Update- und Löschvorgängen zu ermöglichen (die nun auch automatisch
möglich sind). Da Trigger für diese speziellen Beziehungen beim SQL Server 2000 nicht mehr
notwendig sind und auch sehr komplex zu programmieren sind, verzichte ich in diesem Artikel
auf eine weitere Beschreibung dieser Technik.
Zur Herstellung einer Beziehung zwischen einer Master und einer Detailtabelle verwenden Sie
im Enterprise Manager idealerweise ein Diagramm. Falls noch kein Diagramm besteht,
erzeugen Sie (über das Kontextmenü des DIAGRAMME-Eintrags im Datenbank-Ordner) ein
neues und fügen die betroffenen Tabellen hinzu.
Abbildung 25: Erstellen eines neuen Diagramms
Erzeugen und Verwalten von Tabellen 49
Abbildung 26: Diagramm zur Einrichtung von Tabellen und Beziehungen
Ziehen Sie nun einfach das graue Kästchen neben dem Schlüsselfeld der Mastertabelle auf das
graue Kästchen des Schlüsselfeld der Detailtabelle, in diesem Beispiel also z. B. das Feld
Kunden_Nr aus der Tabelle Kunden auf das Feld Kunden_Nr aus Verträge. Im darauf folgenden
Dialog stellen Sie die Beziehung ein.
Erzeugen und Verwalten von Tabellen 50
Abbildung 27: Dialog zur Einrichtung der Beziehung
Für jede Beziehung können Sie definieren, dass diese bei der Erstellung für bereits existierende
Daten überprüft wird. Wenn bereits Daten gespeichert sind, die der Beziehung nicht entsprechen
(z. B. Verträge mit einer nicht existierenden Kunden-Nummer), können Sie die Option
VORHANDENE DATEN BEI ERSTELLUNG ÜBERPRÜFEN ausschalten. Beachten Sie dabei aber,
dass Sie dann Daten besitzen, die nicht den allgemeinen Regeln der Datenbank entsprechen. Sie
sollten diese Daten idealerweise vor der Erstellung der Beziehung in Ordnung bringen und diese
Option eingeschaltet lassen.
Die Option BEZIEHUNG FÜR REPLIKATION ERZWINGEN bezieht sich auf replizierte
Datenbanken. Ohne diese Option können Sie Daten aus der Tabelle auch dann replizieren, wenn
die entsprechenden Master-Datensätze dort nicht vorhanden sind.
Wenn Sie die Option BEZIEHUNG FÜR INSERT- UND UPDATE-ANWEISUNGEN ERZWINGEN
ausschalten, wird die Beziehung inaktiv. Diese Möglichkeit ist wie schon bei CheckEinschränkungen in Sonderfällen sinnvoll, wenn Sie externe Daten importieren, die u. U. den
definierten Regeln nicht entsprechen. Durch das Ausschalten der Beziehung können Sie die
Daten importieren, danach in einen konsistenten Zustand versetzen (indem Sie die fehlerhaften
Daten korrigieren) und schließlich wieder die Einschränkung aktivieren.
1
=,%
Ist die Option BEZIEHUNG FÜR INSERT- UND UPDATE-ANWEISUNGEN ERZWINGEN
eingeschaltet, können Sie über die Unteroption VERKNÜPFTE FELDER MIT CASCADE
AKTUALISIEREN festlegen, dass der SQL Server Änderungen an dem Wert eines verknüpften
Primärschlüsselfeldes in der Mastertabelle automatisch an die Detailtabelle weitergibt. Ohne
diese Option kann ein Primärschlüsselwert nicht geändert werden wenn dieser in einer
Detailtabelle in einem Fremdschlüsselfeld gespeichert ist. Verwenden Sie diese Option immer
dann, wenn Sie das Ändern des Primärschlüsselwertes in der Mastertabelle auch dann
ermöglichen wollen, wenn bereits Datensätze in Beziehung stehen. Normalerweise sollten Sie
diese Änderungen allerdings vermeiden, da Primärschlüsselwerte in Unternehmen häufig eine
besondere Bedeutung besitzen und nicht änderbar sein sollen wenn diese bereits in
Detailtabellen verwendet werden.
Erzeugen und Verwalten von Tabellen 51
Die Option VERKNÜPFTE DATENSÄTZE MIT CASCADE LÖSCHEN ermöglicht das Löschen von
Datensätzen aus der Mastertabelle auch dann, wenn die entsprechenden Primärschlüsselwerte in
der Detailtabelle verwendet werden (was ohne diese Option nicht möglich ist). So können Sie z.
B. eine Bestellung löschen womit automatisch alle bestellten Artikel gelöscht werden.
Gehen Sie sehr vorsichtig mit dieser Option um. Wenn Sie diese Option z. B. in der
Beziehung zwischen der Kunden- und der Verträge-Tabelle einschalten, werden
automatisch alle Verträge eines Kunden gelöscht, wenn dieser Kunde gelöscht
wird. In normalen Datenbanken ist solch ein Verhalten nicht erwünscht, da dabei in
vielen Fällen Daten verloren gehen.
Nachdem Sie die Beziehungen definiert haben, zeigt das Diagramm diese an, wobei jedoch die
in Beziehung stehenden Felder korrekt dargestellt werden.
Abbildung 28: Diagramm mit definierten Beziehungen
Wenn Sie das Diagramm abspeichern, werden die Fremdschlüssel angelegt.
In einem Diagramm können Sie auch die Spalten der Tabellen verändern.
Eine 1:N-Beziehung realisieren Sie, indem Sie das Schlüsselfeld in der Detailtabelle nicht oder
nicht eindeutig indizieren. Eine 1:1-Beziehung erstellen Sie, indem Sie das Schlüsselfeld in der
Detailtabelle eindeutig indizieren. Wenn Sie zulassen, das in das Schlüsselfeld der Detailtabelle
Nullwerte eingegeben werden können, muss kein Datensatz der Mastertabelle in Beziehung mit
dem Datensatz der Detailtabelle stehen; der Anwender muss keinen Masterdatensatz auswählen.
Da Sie die Nullwert-Einstellung nur bei einer neuen Tabelle editieren können, müssen Sie also
beim Anlegen der Tabellen bereits wissen, wie die Beziehung genau aussehen soll.
Erzeugen und Verwalten von Tabellen 52
Wenn Sie nun an die Detailtabelle einen Datensatz anfügen oder editieren wollen, für den kein
Datensatz in der Mastertabelle existiert, erzeugt der Server einen Fehler folgender Form
(Beispiel):
Server: Nachr.-Nr. 547, Schweregrad 16, Status 1, Zeile 1
Die INSERT-Anweisung verstieß gegen die COLUMN FOREIGN KEY-Einschränkung
'FK_Verträge_Standorte'. Der Konflikt trat in der Fahrradverleih-Datenbank,
Tabelle 'Standorte', column 'Standort_Nr' auf.
Die Anweisung wurde beendet.
Wenn Sie einen Datensatz in der Mastertabelle löschen oder das Schlüsselfeld ändern wollen, zu
dem Datensätze in der Detailtabelle existieren, wird ein ähnlicher Fehler erzeugt (sofern die
kaskadierende Aktualisierungs- bzw. Löschweitergabe nicht eingeschaltet ist):
Server: Nachr.-Nr. 547, Schweregrad 16, Status 1, Zeile 1
Die DELETE-Anweisung verstieß gegen die COLUMN REFERENCE-Einschränkung
'FK_Fahrzeuge_Fahrzeugtypen'. Der Konflikt trat in der FahrradverleihDatenbank, Tabelle 'Fahrzeuge', column 'Fahrzeugtyp_Nr' auf.
Die Anweisung wurde beendet.
:/
5
$-
Das Erstellen von Tabellen mit SQL ist oft wesentlich einfacher als die Verwendung des
Enterprise Managers (sofern Sie die SQL-Syntax kennen). Der SQL Server verwendet dazu eine
recht komplexe Variante der CREATE TABLE-Anweisung:
CREATE TABLE [{Datenbankname.[Besitzer]. | Besitzer.}]Tabellenname(
{<Spaltendefinition>
| Spaltenname AS Ausdruck für eine berechnete Spalte
| <Tabelleneinschränkung>}
[,...n]
)
[ON {Dateigruppe | DEFAULT} ]
[TEXTIMAGE_ON {Dateigruppe | DEFAULT} ]
Im Unterschied zu SQL/92 kann hier bei der Erzeugung der Besitzer der Tabelle angegeben
werden. Der Besitzer einer Tabelle besitzt immer alle Rechte auf dieser Tabelle. Per
Voreinstellung ist immer der Benutzer, der die Tabelle anlegt, der Besitzer. Ein weiterer
Unterschied ist, dass statt einer Spaltendefinition auch eine Berechnung für eine berechnete
Spalte angegeben werden kann.
Das folgende Beispiel erzeugt eine Artikeltabelle mit NOT NULL-Spalten, Defaultwerten,
Identity-Spalte und Primärschlüssel ohne Check-Einschränkungen:
CREATE TABLE Products (
ProductID int NOT NULL IDENTITY(1,1) PRIMARY KEY,
ProductName nvarchar(50) NOT NULL,
UnitPrice decimal(10,4) NOT NULL DEFAULT(0),
UnitsInStock int NOT NULL DEFAULT(0),
MinUnitsInStock int NOT NULL DEFAULT(0)
)
Über NOT NULL geben Sie an, dass die Spalte keine NULL-Werte erlaubt. Die Option NULL
würde NULL-Werte für die Spalte erlauben. IDENTITY(1,1) erzeugt eine Identity-Spalte mit
Startwert 1 und Inkrement 1. Die Option PRIMARY KEY bewirkt, dass für diese Spalte ein
Primärschlüssel erzeugt wird. Die Option DEFAULT(0) erzeugt den Defaultwert 0 für die
Spalte.
Erzeugen und Verwalten von Tabellen 53
:/
4 ,
2
Soll der Primärschlüssel über mehrere Felder gehen, müssen Sie die CONSTRAINT-Option (an
Stelle der oben verwendeten PRIMARY KEY-Option) zur Erstellung des Primärschlüssels
verwenden. Diese Variante besitzt zusätzlich den Vorteil, dass Sie den Namen des
Primärschlüssels angeben können.
Das folgende Beispiel erzeugt eine Tabelle Order_Details mit Primärschlüssel auf den Feldern
OrderID und ProductID:
CREATE TABLE Order_Details (
OrderID int NOT NULL,
ProductID int NOT NULL,
Quantity int NOT NULL DEFAULT(0),
CONSTRAINT PK_Order_Details PRIMARY KEY CLUSTERED (OrderID, ProductID)
)
:/"
4 ,
,
##
)
>
Per Default wird der Primärschlüssel mit einem gruppierten (clustered) Index erstellt. Wollen
Sie dies vermeiden (weil Sie einen anderen Index gruppieren wollen), verwenden Sie die
NONCLUSTERED-Option:
CREATE TABLE Order_Details (
OrderID int NOT NULL,
ProductID int NOT NULL,
Quantity int NOT NULL DEFAULT(0),
CONSTRAINT PK_Order_Details PRIMARY KEY NONCLUSTERED (OrderID, ProductID)
)
://
&
,
, 4
Check-Einschränkungen legen Sie idealerweise über die CONSTRAINT-Option an (der SQL
Server bietet auch alternative Möglichkeiten, die CONSTRAINT-Option ist jedoch die
deutlichste).
Das folgende Beispiel erzeugt eine Tabelle Artikel wie oben mit einer Check-Einschränkung auf
dem Feld UnitPrice:
CREATE TABLE Products (
ProductID int NOT NULL IDENTITY PRIMARY KEY,
ProductName nvarchar(50) NOT NULL,
UnitPrice decimal(10,4) NOT NULL DEFAULT(0),
UnitsInStock int NOT NULL DEFAULT(0),
MinUnitsInStock int NOT NULL DEFAULT(0),
CONSTRAINT CK_Products_UnitPrice CHECK(UnitPrice >= 0)
)
Wollen Sie eine Check-Einschränkung (oder jeder anderen Einschränkung) nachträglich
anlegen, verwenden Sie dazu die ALTER TABLE-Anweisung:
ALTER TABLE Products
ADD CONSTRAINT CK_Products_UnitPrice CHECK(UnitPrice >= 0)
Erzeugen und Verwalten von Tabellen 54
:/8
)
Indizes legen Sie separat über die CREATE INDEX-Anweisung an:
CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED]
INDEX index_name ON table (column [,...n])
[WITH
[PAD_INDEX]
[[,] FILLFACTOR = fillfactor]
[[,] IGNORE_DUP_KEY]
[[,] DROP_EXISTING]
[[,] STATISTICS_NORECOMPUTE]
]
[ON filegroup]
Beispiel: Nicht eindeutiger, nicht gruppierter Index mit Füllfaktor 75% auf der Spalte
ProductName:
CREATE NONCLUSTERED INDEX
IX_Products_ProductName ON
Products (ProductName)
WITH
FILLFACTOR=75
Wollen Sie einen vorhandenen Index ändern, müssen Sie den alten zuvor löschen:
DROP INDEX Products.IX_Products_ProductName
oder bei der Erstellung die Option DROP_EXISTING angeben:
CREATE NONCLUSTERED INDEX
IX_Products_ProductName ON
Products (ProductName)
WITH
FILLFACTOR=75,
DROP_EXISTING
:/9
2
,
Fremdschlüssel-Einschränkungen
CONSTRAINT-Option.
, 4
erstellen
Sie
wie
Check-Einschränkungen
über
die
Das folgende Beispiel erzeugt eine Beziehung zwischen der Products- und der Order_DetailsTabelle:
ALTER TABLE Order_Details
ADD CONSTRAINT FK_Order_Details_Products
FOREIGN KEY (ProductID)
REFERENCES Products (ProductID)
:/:
?
, 4
Wollen Sie vorhandene Einschränkungen ändern, müssen Sie die alten Constraints zuvor
löschen. Dazu müssen Sie eine separate ALTER TABLE-Anweisung verwenden:
ALTER TABLE Order_Details
DROP CONSTRAINT FK_Order_Details_Products
ALTER TABLE Order_Details
ADD CONSTRAINT FK_Order_Details_Products
FOREIGN KEY (ProductID)
REFERENCES Products (ProductID)
Erzeugen und Verwalten von Tabellen 55
:/@
?
)
Um einen Index zu löschen, muss der alte zuvor gelöscht werden:
DROP INDEX Products.IX_Products_ProductName
CREATE NONCLUSTERED INDEX IX_Products_ProductName ON Products (ProductName)
:/A
)
)
$#
7
, 4
Informationen zu den Spalten einer Tabelle erhalten Sie über die Stored Procedure sp_columns:
sp_columns products
Informationen zu Einschränkungen werden über die Stored Procedure sp_helpconstraint
ausgegeben:
sp_helpconstraint products
Informationen zu Indizes gibt die Stored Procedure sp_helpindex aus:
sp_helpindex products
:8 ?
5
Beim Ändern von Tabellen benimmt sich der SQL Server recht freundlich. Sie können fast alle
Eigenschaften einer Tabelle ändern, Spalten hinzufügen und löschen. Ändern Sie den Datentyp
einer Spalte, die von anderen Tabellen referenziert wird, ändert der Enterprise Manager die
Spalten in den anderen Tabellen (nach einer Nachfrage) automatisch. Auch Primärschlüssel,
Fremdschlüssel, Check- und Unique-Einschränkungen können Sie nachträglich ändern.
Erzeugen und Verwalten von Tabellen 56
@
@
%
$- $
!
%
Wie Sie schon bemerkt haben, erfordert der SQL Server einen gültigen Login, bestehend aus
Loginname und Passwort, oder den Login über die Windows-Kontoinformationen. Diese
Logins werden im SQL Server gespeichert, können von Benutzern mit entsprechenden Rechten
verwaltet werden und sind Datenbank-übergreifend.
Der Login in den SQL Server kann auf zwei Arten erfolgen: Mit der SQL ServerAuthentifizierung oder mit der Windows-Authentifizierung. Bei der SQL ServerAuthentifizierung muss der Login in den SQL Server explizit bei jedem Verbindungsaufbau
erfolgen. Eine Anwendung kann die Login-Infos beim Aufbau der Verbindung mit übergeben
(z. B. mit ADO in den entsprechenden Login-Argumenten des Connection-Objekts).
Um den Anwendern den Login zu erleichtern, können Sie den SQL Server so konfigurieren,
dass dieser automatisch den Login-Namen und das Passwort verwendet, mit dem der Anwender
sich in Windows eingeloggt hat (Windows-Authentifizierung). Dazu ist allerdings Windows
NT, 2000 oder XP als Server und idealerweise auch als Client erforderlich. Außerdem muss
zum Client eine vertraute Verbindung (trusted Connection) bestehen. Vorteile der WindowsAuthentifizierung sind, dass der Anwender sich nur einmal in Windows einloggen muss und
dass die Logins in Windows verwaltet werden können.
@" !
%
$- $
+ ,
Der SQL Server unterscheidet zunächst systemweite Rechte (wie. z. B. das Recht, Datenbanken
anlegen zu können) und datenbankspezifische Rechte (wie z. B. das Recht, in einer Tabelle
Datensätze anzufügen). Datenbankspezifische Rechte können für jedes Objekt in der Datenbank
für einzelne DB-Benutzer-Objekte vergeben werden. DB-Benutzer-Objekte werden in jeder
Datenbank separat gespeichert. Um einen datenbankübergreifenden Login in den SQL Server zu
ermöglichen, verwaltet dieser zusätzlich zu den DB-Benutzer-Objekten Login-Objekte (die in
der deutschen Version des SQL Servers verwirrenderweise unter „Benutzernamen“ geführt
werden, die englische Version verwendet den Begriff „Logins“). Ein Login-Objekt wird vom
SQL Server automatisch mit einem gleichnamigen DB-Benutzer-Objekt jeder Datenbank
verbunden, auf die dieser Login Zugriff erhält (siehe weiter unten). Der Sinn der getrennten
Verwaltung von Logins und DB-Benutzern ist, dass Sie den DB-Benutzern unterschiedliche
Rechte auf verschiedenen Datenbanken vergeben und auch den Zugriff auf bestimmte
Datenbanken verbieten können.
Sie können einzelnen DB-Benutzern Rechte auf Datenbankobjekte vergeben, besser ist in der
Praxis jedoch die Verwaltung von Rollen und das Zuweisen dieser Rollen zu einzelnen Logins.
Rollen ermöglichen, Rechte gruppenweise zu vergeben. So haben Sie z. B. in einer
Bestelldatenbank eine Rolle „Besteller“. Dieser Rolle weisen Sie Leserechte auf allen Tabellen
und das Recht „Anfügen“ und „Ändern“ auf den Tabellen „Bestellungen“ und „Bestelldetails“
zu. Für jede Person in Ihrer Firma, die Bestellungen aufnehmen soll, legen Sie einen Login an,
vergeben das grundsätzliche Zugriffsrecht auf die Bestelldatenbank und weisen den einzelnen
Logins die Rolle „Besteller“ zu. Sie können einem Login auch mehrere Rollen zuweisen.
Wenn Sie die Windows-Authentifizierung verwenden, können Sie in Windows eine Gruppe
anlegen und dort die einzelnen Benutzer dieser Gruppe verwalten. Im SQL Server müssen Sie
dann nur einen einzelnen Login anlegen, der für diese Windows-Gruppe steht. Jeder Benutzer,
der sich in Windows eingeloggt hat und einer Windows-Gruppe angehört, für die ein Login im
SQL Server existiert, hat damit alle Rechte dieses Logins.
Benutzerverwaltung 57
@/ 2
+
+
$
+
7
Der SQL Server definiert bereits einige feste Server-Rollen und feste Datenbank-Rollen, die Sie
nicht verändern oder löschen können (mit Ausnahme der Public-Rolle) und zu denen Sie keine
neuen Rollen hinzufügen können. Sie können jedoch diese Rollen einzelnen Logins zuweisen.
Benutzerdefinierte Datenbank-Rollen definieren die Zugriffsrechte auf Datenbankobjekten und
werden vom Datenbankbesitzer oder von einem Benutzer angelegt und definiert, der
entsprechende Rechte besitzt.
*
$
+
Rolle
Bedeutung
bulkadmin
Mitglieder dieser Rolle können Massenoperationen wie das Importieren von
externen Daten ausführen.
dbcreator
Mitglieder dieser Rolle können Datenbanken erzeugen und in der Struktur
verändern.
diskadmin
Mitglieder dieser Rolle können Dateien verwalten.
processadmin
Mitglieder dieser Rolle können den SQL Server-Prozess verwalten.
securityadmin
Mitglieder dieser Rolle können die Logins verwalten.
serveradmin
Mitglieder dieser Rolle können Server-weite Einstellungen verwalten
setupadmin
Mitglieder dieser Rolle können Replikationen installieren und Extended
Stored Procedures verwalten.
sysadmin
Mitglieder dieser Rolle können jede Operation auf dem Server ausführen.
Dem Benutzer sa ist diese Rolle per Voreinstellung zugewiesen.
Tabelle 7: Die vordefinierten festen Server-Rollen
*
+
Rolle
Bedeutung
db_accessadmin
Mitglieder dieser Rolle können Benutzer-Objekte von der Datenbank
entfernen oder hinzufügen.
db_backupoperator
Mitglieder dieser Rolle können ein Backup der Datenbank erzeugen.
db_datareader
Mitglieder dieser Rolle können die Daten aller Tabellen der
Datenbank lesen.
db_datawriter
Mitglieder dieser Rolle können die Tabellen der Datenbank
beschreiben.
db_ddladmin
Mitglieder dieser Rolle können Objekte in der Datenbank verändern,
löschen oder hinzufügen.
db_denydatareader
Diese Rolle verweigert alle Leserechte auf alle Objekte der
Datenbank, auch wenn andere Rollen Leserechte vergeben. Damit
können Sie Benutzern, die (zeitweise) »in Ungnade« verfallen sind,
alle Leserechte entziehen, damit diese nicht mehr mit der Datenbank
arbeiten können.
Benutzerverwaltung 58
db_denydatawriter
Diese Rolle verweigert alle Änderungsrechte auf alle Objekte der
Datenbank, auch wenn andere Rollen Änderungsrechte vergeben. Wie
bereits bei der Rolle db_denydatareader können Sie Benutzern,
die (zeitweise) »in Ungnade« verfallen sind, alle Schreibrechte
entziehen.
db_owner
Mitglieder dieser Rolle können alle Operationen auf der Datenbank
ausführen. Diese Rolle definiert dieselben Rechte wie die, die der
DBO besitzt.
db_securityadmin
Mitglieder dieser Rolle können Rollen und die Mitglieder dieser
Rollen und Rechte auf Objekten der Datenbank verwalten.
public
Mitglieder dieser Rolle können nur die Operationen ausführen, für die
explizit Rechte vergeben wurden.
Tabelle 8: Die vordefinierten festen Datenbank-Rollen
Der public-Rolle gehören automatisch alle DB-Benutzer-Objekte (und damit alle Logins) an.
Sie können keinen Benutzer aus der Public-Rolle entfernen. Diese Rolle wird für Rechte
verwendet, die alle Logins, die Zugriff auf eine bestimmte Datenbank besitzen, auf dieser
Datenbank besitzen sollen. Die Public-Rolle ist die einzige feste Rolle, die Sie verändern
können.
Der Database Owner (dbo) ist derjenige Login, der eine Datenbank angelegt hat. Dieser Login
besitzt alle Rechte auf der von ihm angelegten Datenbank. Der SQL Server verknüpft den
Login, der eine Datenbank angelegt hat, automatisch mit dem dbo. In SQL-Anweisungen, in
denen die Angabe des Besitzers eines Objekts notwendig ist, muss immer dbo verwendet
werden, wenn der entsprechende Benutzer eingeloggt ist.
@8
+
Normalerweise werden Sie, nachdem die Datenbankstruktur festgelegt wurde, einzelne Rollen
anlegen und diesen Rollen Rechte auf einzelne Objekte in dieser Datenbank vergeben. Sie
können dabei Rollen auch verschachteln, das heißt, dass sie einer Rolle eine andere Rolle
zuweisen.
Nachdem die Rollen definiert sind, legen Sie wenn notwendig Logins an, geben diesen Logins
Zugriff auf die Datenbank und weisen den Logins die definierten Rollen zu.
Sie können auch jedem einzelnen Login Rechte zuweisen. Wenn Sie die Rechte
aber in Rollen verwalten und den einzelnen Logins diese Rolle(n) zuweisen, wird
die (in der Praxis recht komplexe) Administration der Rechte erheblich vereinfacht.
Idealerweise sollte kein Login spezielle Rechte besitzen, sondern immer nur die,
die über die ihm zugewiesenen Rollen definiert sind. Benötigt ein Benutzer ein
spezielles Recht, erstellen Sie dazu einfach eine neue Rolle und weisen diese dem
Benutzer zu. Sie vermeiden damit ein eventuell entstehendes »Durcheinander« bei
dem Sie in der Praxis u. U. nicht erkennen können, welche Rechte ein Benutzer
nun wirklich besitzt und warum bestimmte Rechte bei bestimmten Benutzern u. U.
nicht verfügbar sind obwohl dies eigentlich der Fall sein sollte.
Benutzerverwaltung 59
Wenn Sie die Windows-Authentifizierung verwenden, können Sie prinzipiell auch
die Windows-Gruppen der Benutzer im SQL Server bekannt machen und diesen
Rechte vergeben. Windows-Benutzer die einer dieser Gruppen angehören, erhalten
damit (theoretisch) alle für die Gruppe definierten Rechten. Im Prinzip können Sie
dann auf Rollen verzichten, da die Windows-Benutzergruppen eine ähnliche
Funktion besitzen. Leider funktioniert diese Technik nach eigenen Erfahrungen
nicht immer. In einigen (speziellen) Architekturen (Windows-NT-Server,
Windows-2000-Clients) wurden in einem meiner Projekte die Gruppenrechte des
Benutzers nicht korrekt ausgewertet, sodass Benutzer bestimmte Rechte nicht
besaßen, die aber ihrer Windows-Gruppe zugewiesen waren. Als Lösung musste
ich die einzelnen Windows-Benutzer im SQL Server bekannt machen und die
Rechte über Rollen verwalten.
@8
+
#
Das Anlegen von Rollen erfolgt im Enterprise-Manager über den ROLLEN-Eintrag. Über das
Kontextmenü legen Sie neue Rollen an:
Abbildung 29: Anlegen einer neuen Rolle
Wenn sie bereits Logins definiert haben, können Sie dieser Rolle in diesem Schritt gleich die
Logins zuweisen.
Benutzerverwaltung 60
B
+ ,
Im nächsten Schritt weisen Sie dieser Rolle Rechte auf die Datenbank zu, was Sie erreichen
können, indem sie auf die Rolle doppelklicken und in den Eigenschaften der Rolle den
Berechtigungen-Schalter betätigen:
Abbildung 30: Einstellung der Zugriffsrechte auf die Objekte einer Datenbank für eine Rolle
Beachten Sie, dass jede Recht-Einstellung für jedes Objekt drei Zustände besitzt: Recht
zugewiesen (Häkchen), Recht nicht zugewiesen (leeres Kästchen) und Recht verweigert (rotes
Kreuz). Wenn ein Benutzer mehreren Rollen zugewiesen ist, wird immer das „sichere“ Recht
verwendet. Wenn ein Recht in einer Rolle verweigert wird, besitzt der Benutzer dieses Recht
nicht, auch wenn das Recht in einer anderen Rolle vergeben wurde. Ist ein Recht in einer Rolle
lediglich nicht vergeben und in einer anderer Rolle vergeben, besitzt ein Benutzer, der beiden
Rollen angehört, dieses Recht.
Benutzerverwaltung 61
%
,
Anweisungsrechte sind solche, die das Erstellen von Datenbankobjekten und das Backup der
Datenbank betreffen. Anweisungsrechte vergeben Sie über die Eigenschaften der Datenbank.
Abbildung 31: Vergabe von Anweisungsrechten in den Datenbank-Eigenschaften
Anweisungsrechte können Sie einzelnen Rollen und einzelnen Benutzern zuweisen.
Benutzerverwaltung 62
@8"
C %
$-
* %
+ ,
Das Zuweisen oder Verweigern von Rechten geht wesentlich einfacher mit SQL als mit dem
Enterprise-Manager. Besonders dann, wenn Sie einer Rolle oder einem Benutzer alle oder fast
alle Rechte vergeben wollen, sind sie mit SQL im Vorteil.
Rechte vergeben Sie mit der GRANT-Anweisung. Für Anweisungsrechte gilt:
GRANT {ALL | statement [,...n]} TO security_account [,...n]
Mit ALL vergeben sie alle Rechte, ansonsten verwenden Sie die folgenden Angaben, um
bestimmte Rechte zu vergeben:
Anweisung
Erlaubt das ...
CREATE DATABASE
Erzeugen von Datenbanken
CREATE DEFAULT
Erzeugen von Default-Wert-Objekten, die als Defaultwert für
Spalten von Tabellen verwendet werden können. Ist lediglich aus
Kompatibilitätsgründen zu älteren Versionen des SQL Servers
enthalten. Verwenden Sie für spezielle Defaultwerte im SQL
Server 2000 besser Funktionen.
CREATE FUNCTION
Erzeugen von Funktionen
CREATE PROCEDURE
Erzeugen von Stored Procedures
CREATE RULE
Erzeugen von Regeln
CREATE TABLE
Erzeugen von Tabellen
CREATE VIEW
Erzeugen von Sichten
BACKUP DATABASE
Sichern von Datenbanken
BACKUP LOG
Sichern des Transaktions-Protokolls
Tabelle 9: Angaben für das Erteilen von Anweisungsrechten
Objektrechte legen sie ähnlich an:
GRANT
{ALL [PRIVILEGES] | permission[,...n]}
{
[(column[,...n])] ON {table | view}
| ON {table | view}[(column[,...n])]
| ON {stored_procedure | extended_procedure}
}
TO security_account[,...n]
[WITH GRANT OPTION]
[AS {group | role}]
Benutzerverwaltung 63
Mit ALL können Sie alle Rechte vergeben. Wenn Sie spezifische Rechte vergeben wollen,
verwenden Sie die folgenden Angaben (nur Auszug, die komplette Liste finden Sie in der
TSQL-Hilfe für die GRANT-Anweisung):
Anweisung
Erlaubt ...
ALTER DATABASE
das Verändern der Datenbankstruktur
ALTER TABLE
das Verändern der Struktur einer Tabelle
ALTER PROCEDURE
das Verändern einer Stored Procedure
ALTER FUNCTION
das Verändern einer Funktion
ALTER VIEW
das Verändern einer Sicht
EXECUTE
den Aufruf von Stored Procedures
GRANT [ON Objekt]
die Vergabe von Rechten für alle Objekte oder das angegebene Objekt
INSERT
das Anfügen von Datensätzen an die angegebene Tabelle
SELECT
das Anfügen von Datensätzen aus der angegebenen Tabelle
UPDATE
das Aktualisieren von Datensätzen in der angegebenen Tabelle
Tabelle 10: Auszug aus den Angaben für das Erteilen von Objektrechten
Das folgende Beispiel vergibt ein Leserecht auf die Tabelle Products für die Rolle Besteller:
GRANT SELECT ON Products TO Besteller
Sie können auch spaltenweise Rechte vergeben, indem sie die Spalten in Klammern vor dem
Objekt angeben.
Das folgende Beispiel vergibt das Aktualisierungsrecht auf die Spalten ProductName und
UnitPrice der Tabelle Products an die Rolle Besteller:
GRANT UPDATE (ProductName, UnitPrice) ON Products TO Besteller
Entfernen können Sie Rechte über REVOKE. Wenn Sie ein Recht explizit verweigern wollen,
verwenden Sie DENY. Beide Anweisungen arbeiten mit einer der GRANT-Anweisung ähnlichen
Syntax. REVOKE entfernt nicht nur ein vergebenes Recht, sondern auch die Verweigerung eines
Rechts.
@8/
Wenn Sie Ihre Datenbank(en) und die zugehörigen Rollen angelegt haben, können sie im
nächsten Schritt im Enterprise-Manager Logins anlegen, diesen Logins Zugriff auf die
Datenbanken gewähren und den Logins die definierten Rollen zuweisen. Das Anlegen und
Modifizieren von Logins geschieht über den BENUTZERNAMEN-Eintrag im SICHERHEIT-Ordner
im Enterprise-Manager.
Benutzerverwaltung 64
Abbildung 32: Definieren von Logins
Hier können sie auch einstellen, ob für diesen Login die Windows-Authentifizierung verwendet
wird oder die SQL Server-Authentifizierung. Daneben stellen sie ein, welche Datenbank die
Default-Datenbank ist, wenn der Benutzer (oder eine Anwendung) keine spezielle Datenbank
angibt.
Im Register SERVERROLLEN können Sie angeben, welchen festen Server-Rollen der Login
zugewiesen ist. Im Register DATENBANKZUGRIFF legen Sie fest, auf welche Datenbanken der
Login grundsätzlichen Zugriff besitzt und welchen Rollen der Login zugewiesen ist.
Benutzerverwaltung 65
Abbildung 33: Vergabe der Zugriffsrechte auf Datenbanken und Festlegen der Rollen
Beachten Sie, dass sie in der oberen Liste zuerst die Datenbank auswählen müssen, um dem
Login in der unteren Liste die Rollen zuweisen zu können.
Für jeden Login legt der SQL Server automatisch einen Benutzer in der Datenbank an, der
denselben Namen besitzt wie der Login. Diesen Benutzer können sie in der Datenbank separate
Rechte vergeben, die der Login über seine Rollen nicht besitzt. Normalerweise reicht es jedoch
aus, Rechte in Rollen zu definieren und einzelnen Logins diese Rollen zuzuweisen.
@9
@9
$- $
Bei der SQL Server-Authentifizierung erfolgt der Login bei jedem Aufbau einer Verbindung
explizit. Eine Anwendung muss beim Aufbau der Verbindung den Login-Namen und das
Passwort an den SQL Server übergeben. Der Login muss mit dem Login-Namen und dem
Passwort im SQL Server definiert sein, damit die Verbindung zustande kommen kann. Für diese
Logins muss eingestellt sein, dass die SQL Server-Authentifizierung verwendet wird.
@9"
!
%
Wenn auf allen Clients Windows NT, 2000, XP oder eine neuere Version verwendet wird,
können Sie die Windows-Authentifizierung verwenden. Die Benutzer müssen sich dann nicht
explizit in den SQL Server einloggen, da dieser die Informationen des Windows-Kontos des
aktuellen Benutzers verwendet. Verwenden Sie die Windows-Authentifizierung nicht, muss ein
Benutzer sich einmal in Windows und dann noch einmal in den SQL Server einloggen.
Benutzerverwaltung 66
Im Idealfall verwalten sie alle SQL Server-Benutzer in Windows-Gruppen, denen sie jeweils
einen SQL Server-Login zuweisen. Somit können Sie die Benutzer in Windows verwalten und
die Rechte dieser Benutzer über den Login im SQL Server. Eine andere Möglichkeit ist, für
jeden Windows-Benutzer einen separaten Login im SQL Server zu verwalten.
Nach meinen Erfahrungen in einem Projekt kann es zu Problemen kommen wenn
Sie nur die Benutzergruppen im SQL Server verwalten. Aus nicht
nachvollziehbaren Gründen wurden bestimmte Rechte bestimmter Benutzer nicht
korrekt erkannt, obwohl die Windows-Gruppe dieser Benutzer diese Rechte besaß.
In diesem Projekt musst ich alle Benutzer einzeln im SQL Server bekannt machen
und die Rechte über Rollen verwalten, damit alles reibungslos funktionierte. Das
muss bei Ihnen nicht so sein, wenn Sie allerdings ähnliche Probleme haben,
versuchen Sie einmal meine Lösung ...
Nehmen wir an, Sie haben in der Windows-Domäne THE_GALAXY eine Gruppe Verleiher
definiert, der bestimmte Anwender angehören. Für diese Gruppe erzeugen Sie im SQL Server
einen Login, dem Sie die Windows-Gruppe zuweisen.
Abbildung 34: Erzeugen eines Login für einen Windows-Benutzer
Alle Benutzer, die einer Windows-Gruppe zugehören, besitzen damit automatisch alle Rechte
des Logins, der die Windows-Gruppe im SQL Server abbildet. Sie können die der Gruppe
zugehörigen Benutzer unter Windows verwalten, was auch noch den Vorteil hat, dass sie die
Zugriffsrechte auf das System (also z. B. auf einzelne Dateien) gleichzeitig mit dem
Zugriffsrechten für den SQL Server verwalten können.
Wenn sie einzelne Windows-Benutzer einzelne Logins zuweisen wollen, geben Sie im Namen
des Logins statt des Gruppennamens einfach dem Namen des Benutzers an.
In der Regel kann der Client entscheiden, ob nun die SQL Server-Authentifizierung oder die
Windows-Authentifizierung verwendet wird. Verwendet der Client zum Beispiel ADO zum
Datenzugriff, wird beim Herstellen der Verbindung eingestellt, welche Art der
Benutzerverwaltung 67
Authentifizierung verwendet wird. Der Query Analyzer (der ADO zum Zugriff auf den SQL
Server verwendet) ist ein gutes Beispiel für diese Entscheidung.
Abbildung 35: Login in den SQL Server durch den Query Analyzer
@ : $#
Der SQL Server unterstützt Benutzernamen und Logins mit spezieller Bedeutung:
$6
' (
Der Login sa stellt den Systemadministrator mit allen Rechten auf allen Objekten der
Datenbank dar. Für den Systemadministrator-Login führt der SQL Server keinerlei
Überprüfungen durch, d.h., der Systemadministrator arbeitet jenseits aller Schutzmechanismen
und kann deshalb jede gewünschte Operation durchführen. Er ist gleichzeitig der einzige
Eigentümer der Master-Datenbank und wird automatisch allen neu erstellten Datenbanken als
Miteigentümer assoziiert. Der sa kann zeitweise die Identität anderer Benutzer annehmen:
SetUser Name
Damit kenn er z. B. für diesen Benutzer Objekte anzulegen. Mit SetUser ohne Parameter wird
diese Zuweisung wieder aufgehoben.
0
Guest ist ein Benutzer, der vom Server verwendet wird, wenn ein Anwender mit einem gültigen
Login, jedoch keinem gültigen Benutzer sich anmeldet. Dieser Login erhält dann die Rechte des
Benutzers Guest falls dieser Benutzer definiert ist.
'
(
Der dbo (Database Owner) ist der Benutzer, der eine Datenbank erstellt hat. Der dbo besitzt
immer alle Rechte auf der betreffenden Datenbank und kann anderen Benutzern Rechte
zuweisen oder entziehen. Eine Datenbank kann immer nur einem Benutzer gehören. Der
Besitzer einer Datenbank kann nachträglich geändert werden.
B
Jeder Benutzer, der ein Datenbankobjekt erstellt hat wird zum Besitzer dieses Objekts und
verfügt innerhalb seines Objekts über alle Berechtigungen.
Benutzerverwaltung 68
A $,
7$
,
72
5
A
Eine Sicht (engl. View, eine spezielle „Sicht“ auf die Daten) ist eine gespeicherte
Auswahlabfrage. Über eine Sicht können Sie
•
komplexe Abfragen vor Clients verbergen. So können Sie zum Beispiel eine komplexe
Abfrage in einer Sicht speichern. Ein Client führt nur einen SELECT, UPDATE, INSERT oder
DELETE auf dieser Sicht aus und weiß nichts von der Komplexität der zugrunde liegenden
Abfrage.
•
Benutzern Zugriffsrechte auf Tabellen oder Spalten geben, auf die diese normalerweise
keine Rechte besitzen.
•
die Sicherheit komplexer verwalten, als dies mit Zugriffsrechten allein möglich ist (Beispiel
dazu siehe unten).
•
die Performance erhöhen, da eine Sicht in der Datenbank bereits kompiliert ist und im SQL
Server 2000 auch separat indiziert werden kann.
Eine Stored Procedure ist eine in TSQL (Transact SQL, der dem SQL Server spezifische SQLDialekt) geschriebene SQL-Prozedur. TSQL erlaubt im Gegensatz zu ASCII-SQL einfache
Programmstrukturen wie IF-Abfragen, WHILE-Schleifen und Variablen. TSQL besitzt
besondere Bedeutung für Stored Procedures, Funktionen und Trigger. Stored Procedures können
wie eine normale Funktionen Parameter besitzen, in denen sogar Werte zurückgegeben werden
können, und als Funktion eine oder mehrere Datensatzlisten und einen Integerwert zurückgeben.
Stored Procedures werden verwendet, um einen Teil der Geschäftslogik auf den Server zu
verlagern. Oft bringt eine Stored Procedure, die eine bestimmte Aktion ausführt, einen
Geschwindigkeitsvorteil gegenüber der Programmierung dieser Aktion in der Anwendung. Ein
wesentlicher Vorteil von Stored Procedures ist jedoch, dass diese sehr einfach zentral auf dem
Server gepflegt werden können. Eine Aktualisierung einer Stored Procedure ist sofort für alle
Clients sichtbar, die diese verwenden.
Die wesentliche Anwendung von TSQL erläutere ich im Folgenden bei der
Beschreibung von Stored Procedures. Da Sie TSQL aber auch in Funktionen und
Triggern einsetzen können, gilt alles das, was Sie zu TSQL bei den Stored
Procedures lesen, auch für Funktionen und Trigger.
Funktionen (neu im SQL Server 2000) sind das was sie auch in der Programmierung sind:
Funktionen, denen Argumente übergeben werden können und die einen Wert zurückliefern. Das
Besondere an SQL-Server-Funktionen ist, dass diese in SQL verwendet werden können, also in
Abfragen, Sichten, Stored Procedures, Triggern und natürlich auch in anderen Funktionen. Mit
Hilfe von Funktionen können Sie, wie bei Stored Procedures, einen Teil der Anwendungslogik
bereits in der Datenbank speichern. So können Sie z. B. eine Funktion schreiben, die den
gültigen Mehrwertsteuer-Prozentwert abhängig von einem übergebenen Datum zurückgibt.
Wenn Sie diese Funktion überall dort einsetzen, wo die Mehrwertsteuer benötigt wird (in
Sichten, Abfragen, Stored Procedures etc.), können Sie eventuelle Änderungen des
Mehrwertsteuersatzes für zukünftige Datumswerte sehr einfach in der Datenbank
berücksichtigen indem Sie einfach die Funktion umschreiben.
Trigger sind Stored Procedures ähnlich. Der Unterschied ist, das Stored Procedures von außen
aufgerufen werden, wogegen Trigger implizit aufgerufen werden, wenn auf eine Tabelle eine
UPDATE, INSERT oder DELETE-Operation ausgeführt wird. Ein Trigger gilt immer für eine
Tabelle und kann entweder nur auf UPDATE, INSERT oder DELETE reagieren oder auf eine
Kombination dieser Aktionen. Ein Trigger besitzt zudem, im Gegensatz zu Stored Procedures,
Sichten, Stored Procedures, Funktionen und Trigger 69
keine Parameter und kann keine Werte oder Datensatzlisten zurückgeben. Mit Hilfe eines
Triggers kann z. B. eine komplexe Integritätsregel für einzelne Felder implementiert werden.
Sinnvoll ist z. B. ein Trigger, der beim Anfügen neuer Datensätze in einer Kunden-Tabelle die
nächste freie Kundennummer ermittelt und automatisch in das Feld Kunden_Nr einfügt oder ein
Trigger, der beim Aktualisieren eines Kunden das Datum der letzten Änderung in einem
entsprechenden Datumsfeld aktualisiert.
A " $,
A"
$,
Sichten können Sie recht einfach erzeugen, indem Sie im Kontextmenü des SICHTEN-Ordners
im Enterprise Manager NEUE SICHT wählen. Der Enterprise Manager bietet Ihnen ein grafisches
Tool zur Erstellung der Abfrage, das Sie recht einfach auch für komplexe Abfragen verwenden
können.
Abbildung 36: Der graphische Abfrage-Editor zum Erstellen von Sichten
Das Schöne an diesen Editor ist, dass die Abfrage syntaktisch immer korrekt ist.
In SQL erzeugen sie eine Sicht über:
CREATE VIEW Sichtname [(Spaltenliste)] [WITH ENCRYPTION] AS
Select_Anweisung
[WITH CHECK OPTION]
In der Abfrage geben Sie eine SELECT-Anweisung an. Basiert die Abfrage auf mehr als einer
Tabelle, können Sie die Spaltennamen für Spalten, deren Name mehrfach vorkommen, in der
optionalen Spaltenliste anpassen (einfacher wäre allerdings, die Spalten mit der AS-Klausel in
der Abfrage umzubenennen). Die CHECK OPTION wird weiter unten erläutert.
Sichten, Stored Procedures, Funktionen und Trigger 70
Das folgende Beispiel erzeugt eine Sicht auf die Produkte der Datenbank Northwind und deren
Kategoriename:
CREATE VIEW Products_With_Category_Name AS
SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
FROM Products INNER JOIN Categories
ON Products.CategoryID = Categories.CategoryID
Wie bereits oben beschrieben, können Sie über eine Sicht Anwendern Zugriff auf Daten geben,
auf die diese normalerweise keinen Zugriff hätten, und komplexe Abfragen gegenüber
Anwendern bzw. Clients verbergen. Sichten bieten außerdem den Vorteil, dass die Abfrage
bereits kompiliert ist und deswegen etwas schneller ausgeführt wird, als normale an den Server
gesendete Abfragen.
A""
* %
$,
Sichten werden verwendet wie Tabellen. Sie können Auswahlabfragen, aber auch
Aktualisierungs-, Anfüge- und Löschabfragen auf der Sicht ausführen. Voraussetzung dafür ist
allerdings, dass die der Sicht zugrunde liegende Abfrage das Aktualisieren, Anfügen bzw.
Löschen zulässt.
Das folgende Beispiel erzeugt eine Sicht, die alle Produkte der Kategorie 1 auflistet:
CREATE VIEW Products_Of_Cat1 AS
SELECT * FROM Products WHERE CategoryID = 1
Eine Auswahlabfrage würde dann z. B. folgendermaßen aussehen:
SELECT * FROM Products_Of_Cat1 WHERE SupplierID = 16
Eine Aktualisierungsabfrage würde z. B. so aussehen:
Update Products_Of_Cat1 SET UnitPrice = UnitPrice * 1.2 WHERE SupplierID = 16
Bei der Abfrage müssen Sie bedenken, dass die Sicht die Datensätze eventuell bereits
einschränkt. Die Beispiel-Sicht zeigt z. B. grundsätzlich nur die Produkte der Kategorie 1. Eine
Abfrage auf die Sicht berücksichtigt dann natürlich nur diese Produkte.
A"/
$
$,
Der SQL Server erlaubt keine direkten Sortierungen in Sichten. Das ist sinnvoll, denn eigentlich
soll derjenige, der die Sicht später aufruft, eine spezielle Sortierung angeben können. In einigen
Fällen ist es aber sinnvoll, eine Sicht schon per Voreinstellung zu sortieren. Über einen kleinen
Trick ist dies möglich: Der SQL Server erlaubt das Sortieren in einer Sicht, wenn die TOPKlausel verwendet wird. Mit TOP 100 PERCENT können Sie nun alle Daten auslesen und
trotzdem sortieren:
CREATE VIEW Products_With_Category_Name AS
SELECT TOP 100 PERCENT Products.ProductID, Products.ProductName,
Categories.CategoryName
FROM Products INNER JOIN Categories
ON Products.CategoryID = Categories.CategoryID
ORDER BY Products.ProductName
U. U. wird die Sicht mit TOP 100 PERCENT etwas langsamer ausgeführt als wenn
diese nachträglich sortiert wird, was besonders dann gilt, wenn die Sicht beim
Aufruf sortiert wird. Sie sollten dies in der Praxis einfach testen. Hilfreich dabei ist
der SQL Profiler, den Sie über das EXTRAS-Menü Des Enterprise-Managers
aufrufen können.
Sichten, Stored Procedures, Funktionen und Trigger 71
A"8
&
,
#
Normalerweise erlaubt eine Sicht:
•
die enthaltenen Datensätze so zu ändern, dass diese nicht mehr den Kriterien (der WHEREKlausel) entsprechen und folglich aus der Sicht (beim nächsten Aufruf) entfernt werden;
•
neue Datensätze anzufügen, die den Kriterien der Sicht entsprechen und beim nächsten
Aufruf der Sicht nicht erscheinen.
Das folgende Beispiel ändert die Kategorie der Produkte, die vom Lieferant 16 geliefert werden,
über die Sicht Products_of_Kat1:
UPDATE Products_Of_Cat1 SET CategoryID = 2 WHERE SupplierID = 16
Genauso können Sie über diese Sicht z. B. auch ein Produkt hinzufügen, das der Kategorie 2
angehört:
INSERT INTO Products_Of_Cat1
VALUES ('Test', 16, 2, NULL, 11.25, 0, 0, 10, 0)
Dieses nicht intuitive Verhalten der Sicht können Sie mit der Check-Option unterbinden:
CREATE VIEW Products_Of_Cat1 AS
SELECT * FROM Products WHERE CategoryID = 1
WITH CHECK OPTION
Eine Abfrage, die die enthaltenen Datensätze so ändert, dass diese aus der Sicht entfernt würden
oder neue Datensätze anfügt, die nicht in der Sicht erscheinen würden, schlägt nun mit einer
Fehlermeldung fehl.
A"9
%
$,
$,
Da Sie in Sichten auch Systemfunktionen einsetzen können, können Sie mit diesen auch eine
erweiterte Sicherheit in ihrer Datenbank realisieren.
Eine sinnvolle Anwendung wäre zum Beispiel die folgende: Ein Trigger sorgt in Ihrer
Datenbank dafür, dass der Benutzer, der einen Datensatz in der Bestelltabelle anlegt, mit seinem
Login Namen in einem speziellen Feld der Tabelle festgehalten wird. Keinem der
Sachbearbeiter, die Bestellungen bearbeiten können, wird das Anfüge-, das Auswahl-, das
Lösch- und das Aktualisierungsrecht auf die Bestelltabelle direkt vergeben. Diese Rechte
werden einer Sicht vergeben, die folgendermaßen definiert ist:
CREATE VIEW User_Orders AS
SELECT OrderId, OrderDate, CustomerId FROM Orders
WHERE User_Created = SESSION_USER
WITH CHECK OPTION
In dieser Sicht wird die Systemfunktion SESSION_USER verwendet, die den Namen des Logins
zurückgibt, der die Sicht aufgerufen hat.
Da eine Sicht grundsätzlich wie eine Tabelle verwendet werden kann, kann nun jeder
Sachbearbeiter ausschließlich seine eigenen Bestellungen sehen und bearbeiten. Voraussetzung
dafür ist natürlich, dass alle Anwendung diese Sicht an Stelle der Tabelle verwenden.
Idealerweise besitzen die Sachbearbeiter in diesem Beispiel auf der Tabelle selbst keine Rechte,
sondern nur auf der Sicht.
Sichten, Stored Procedures, Funktionen und Trigger 72
A":
$,
4
Sichten können Sie sehr einfach über die ALTER-Anweisung verändern:
CREATE VIEW Products_Of_Cat1 AS
SELECT * FROM Products WHERE CategoryID = 1
WITH CHECK OPTION
Vorteil dabei ist, dass der SQL Server Rechte, die auf die Sicht gesetzt sind, beibehält, was nicht
der Fall wäre, wenn Sie die Sicht löschen und wieder neu erzeugen würden.
A/ $
A/
,
$
,
Eine Stored Procedure definieren Sie recht einfach, indem Sie im Enterprise Manager im
Kontextmenü des Ordners GESPEICHERTE PROZEDUREN in einem Datenbank-Ordner den Befehl
NEUE GESPEICHERTE PROZEDUR wählen. Im Dialog zur Erstellung von Stored Procedures wird
Ihnen eine neue Stored Procedure angezeigt.
Abbildung 37: Das Fenster zum Erstellen und Verändern von Stored Procedures
Stored Procedures gelten immer für eine Datenbank und können tabellenübergreifend arbeiten.
Geben Sie zunächst für <PROCEDURE NAME> einen Namen für Ihre Stored Procedure ein.
Sichten, Stored Procedures, Funktionen und Trigger 73
Abbildung 38: Einfache Stored Procedure vor dem Speichern
Achten Sie besonders auf die korrekte Schreibweise von verwendeten Bezeichnen,
also Spaltennamen und Tabellennamen. Sie können über den Schalter SYNTAX
ÜBERPRÜFEN zwar die grundsätzliche Syntax der Stored Procedure testen, aber
nicht, ob verwendete Tabellen oder Spalten auch existieren.
Speichern Sie diese Stored Procedure über den OK-Schalter. Kann die Stored Procedure
gespeichert werden (d. h, dass sie keine Fehler enthält), fügt der Manager automatisch Code
hinzu, der beim Speichern dafür sorgt, dass zuvor eine bereits definierte gleichnamige Stored
Procedure gelöscht wird.
Testen können Sie Stored Procedures über den Query Analyzer über die EXECUTE-Anweisung
(die allerdings optional ist). Für unser Beispiel wäre ein Aufruf z. B.:
EXECUTE Get_Kunden
Eine Stored Procedure kann mit derselben Syntax auch mit SQL direkt erzeugt werden:
CREATE PROC[EDURE] procedure_name [;number]
[
{@parameter data_type} [VARYING] [= default] [OUTPUT]
]
[,...n]
[WITH
{
RECOMPILE
| ENCRYPTION
| RECOMPILE, ENCRYPTION
}
]
[FOR REPLICATION]
AS
sql_statement [...n]
Sichten, Stored Procedures, Funktionen und Trigger 74
A/"
+ ,
6#
$
,
Eine Stored Procedure kann eine oder mehrere Datensatzlisten und/oder einen Integer-Datentyp
zurückgeben. Nur das Ergebnis einer Stored Procedure, die eine Datensatzliste zurückgibt,
können Sie im SQL Query Analyzer direkt sehen. Für alle anderen kommt nur die Meldung,
dass diese keine Datensatzlisten zurückgeben.
Eine Datensatzliste wird immer dann zurückgegeben, wenn Sie mit innerhalb der Stored
Procedure eine normale Auswahlabfrage (also eine Abfrage, die einzelne Felder zurückgibt)
schreiben. Da Sie mit einer SELECT-Anweisung auch Variablen Werte zuweisen können, muss
ein solches nicht immer auch eine Datensatzliste zurückgeben. Das Beispiel oben gibt alle
Felder der Products-Tabelle zurück:
SELECT * FROM Products
Die Rückgabe als Datensatzliste muss jedoch nicht unbedingt einer Tabelle entnommen werden.
So können Sie mit SELECT auch selbstdefinierte Datensatzlisten zurückgeben. Die folgende
Abfrage:
SELECT "Hello World" AS Begrüßung, "Jürgen" AS Name
ergibt z. B.
Begrüßung
Name
----------- -----Hello World Jürgen
(1 row(s) affected)
Wenn eine Stored Procedure einen Integer-Datentyp zurückgeben soll, geben Sie diesen mit
RETURN Wert
zurück.
Für den Wert können Sie natürlich auch eine Variable oder einen Ausdruck einsetzen. Beachten
Sie, dass eine Stored Procedure nur Integer-Datentypen zurückgeben kann, keine anderen Werte
wie z. B. Dezimalwerte oder Zeichenketten. Wenn Sie z. B. eine real-Variable mit RETURN
@Variable zurückgeben, konvertiert der SQL Server den Wert in den entsprechenden
Integerwert um. Wenn Sie Dezimal-Datentypen oder Zeichenketten zurückgeben wollen,
müssen Sie dazu OUTPUT-Argumente verwenden (siehe weiter unten).
Eine solche Rückgabe kann beim Aufruf einer Stored Procedure aus einer Anwendung heraus
verwendet werden. Wie dies für ein VBA-Programm implementiert wird, erfahren Sie weiter
unten. Sinnvoll ist die Verwendung eines Rückgabewertes immer dann, wenn eine Stored
Procedure eine Aktion ausführen soll, die gar keine Datensatzliste ergibt, z. B. den Update eines
Artikel-Preises in der Artikeltabelle, oder wenn der Erfolg einer Aktion ausgewertet werden
soll.
Eine weitere Möglichkeit, Werte zurückzugeben, ist die Verwendung von OUTPUT-Parametern,
die ich im nächsten Abschnitt beschreibe.
A//
*
Eine Stored Procedure kann in der Parameterliste, die in Klammern dem Prozedurnamen folgt,
Input- und Output-Parameter besitzen. Ein Parameter wird durch
@Name Datentyp [VARYING] [= default] [OUTPUT]
deklariert. Der Name folgt den üblichen Regeln für Bezeichner (beginnt mit einem Buchstaben,
kann Zahlen, Buchstaben und den Unterstrich enthalten). Der Datentyp entspricht den unten
beschriebenen Datentypen für Variablen.
Sichten, Stored Procedures, Funktionen und Trigger 75
Beispiel: Stored Procedure, der eine Kunden-Nummer übergeben wird, und die den Kunden mit
dieser Kunden-Nummer zurückgibt:
CREATE PROCEDURE Get_Kunde(@Kunden_Nr int) AS
SELECT * FROM Kunden WHERE Kunden_Nr = @Kunden_Nr
Wenn Sie über einen Parameter Werte zurückgeben wollen, geben Sie OUTPUT mit an. OutputParameter werden weiter unten beschrieben.
Mit der Option VARYING können Sie in Parametern Datensatzlisten zurückgeben. Der Parameter
muss dazu ein Cursor-Datentyp sein. Da Sie dies wahrscheinlich nur in sehr komplexen
Programm benötigen, wird diese Option hier nicht beschrieben.
Wenn Sie einen Defaultwert angeben, muss beim Aufruf der Prozedur anstelle dieses Parameter
kein Wert übergeben werden. Wird kein Wert übergeben, verwendet die Prozedur den
Defaultwert.
Da Sie in TSQL auch programmieren können, benötigen sie in vielen Stored Procedures auch
Variablen. Variablen werden folgendermaßen deklariert:
DECLARE @Name Datentyp [,@Name Datentyp] [...]
Das @-Zeichen vor dem eigentlichen Namen ist für Parameter und Variablen obligatorisch.
Für Parameter und Variablen können Sie fast alle der in Kapitel 6.1.1 beschriebenen Datentypen
verwenden. Häufig werden die Typen int, double und nvarchar(n) eingesetzt.
Sie können einem Parameter oder einer Variablen mit
SET @Variable = Wert
einen Wert zuweisen.
Das folgende Beispiel speichert einen Parameterwert in einer Variablen:
CREATE PROCEDURE Get_Kunde(@Kunden_Nr int) AS
DECLARE @ID int
SET @ID = @Kunden_Nr
SELECT * FROM Kunden WHERE Kunden_Nr = @ID
Einer Variablen können Sie außerdem einen Wert über eine Auswahlabfrage zuweisen:
SELECT @Variable=Ausdruck FROM ...
Der Ausdruck ist in der Regel ein einfaches Datenfeld, eine arithmetische Berechnung, oder
eine Aggregatfunktion.
Außerdem können Sie Parameter oder Variablen in einer Abfrage einsetzen. Das folgende
Beispiel holt die größte ProductID aus der Tabelle Products und gibt diese um 1 addiert zurück:
CREATE PROCEDURE Get_Next_ProductId AS
/* Deklaration einer Variablen */
DECLARE @ProductID int
/* Zuweisen der größten ProductID zu der Variablen @ProductID */
SELECT @ProductID = MAX(ProductID) FROM Products
/* Rückgabe einer selbst erzeugten Datensatzliste (mit einem
Datensatz) mit dem Ergebnis */
SELECT @ProductID + 1 AS Next_Product_Id
Dieses Beispiel gibt die ermittelte ProductID in einer Datensatzliste mit einem einzigen
Datensatz und einem Feld Next_Product_Id zurück. Beachten Sie, dass die erste SELECTAnweisung keine Datensatzliste ergibt, weil ausschließlich Zuweisungen an Variablen erfolgen.
Das Ergebnis der Stored Procedure ist also nur eine Datensatzliste.
Sinnvollerweise könnte die Stored Procedure den ermittelten Wert direkt als
Funktionsrückgabewert zurückgeben (beachten Sie dabei, dass Stored Procedures nur IntegerWerte im Funktionsrückgabewert zurückgeben können):
Sichten, Stored Procedures, Funktionen und Trigger 76
CREATE PROCEDURE Get_Next_ProductId AS
/* Deklaration einer Variablen */
DECLARE @ProductID int
/* Zuweisen der größten ProductID zu der Variablen @ProductID */
SELECT @ProductID=MAX(ProductID) FROM Products
/* Rückgabe einer selbst erzeugten Datensatzliste (mit einem
Datensatz) mit dem Ergebnis */
RETURN @ProductID + 1
Wollen Sie Prozeduren, die einen Integer-Wert zurückgeben, testen, müssen sie diese im Query
Analyzer etwas anderes aufrufen:
DECLARE @ProductID int
EXECUTE @ProductID = Get_Next_ProductId
SELECT @ProductID AS Next_ProductID
* %
#
Output-Parameter sind äquivalent zu By Reference-Argumenten in Programmiersprachen wie
C, C++, C#, oder Visual Basic(.NET). In Output-Parametern können Sie Werte beliebigen
Datentyps zurückgeben, was besonders bei Stored Procedures interessant ist, da diese im
Funktionsrückgabewert nur Integer-Werte zurückgeben können.
Die Verwendung von Output-Parametern ist eigentlich recht einfach. Deklarieren Sie einen
Parameter einfach mit OUTPUT. Werte, die Sie (mit SET oder SELECT) in diesen Parameter
schreiben, können nach dem Aufruf der Stored Procedure in einer Anwendung sehr einfach
ausgelesen werden. Wie das prinzipiell funktioniert, erfahren Sie im nächsten Abschnitt.
A/8
$
,
#
*
Stored Procedures werden häufig in programmierten Anwendungen eingesetzt, um möglichst
viel von der Geschäftslogik in den Server zu verlagern. Man spricht hier übrigens von einem 2Schichten-Modell (oder 2-Tier-Model). Die Benutzerschicht stellt die für die Bearbeitung der
Daten erforderlichen Oberflächen dar, die Datenschicht speichert die Daten. Bei 2-SchichtenModellen liegt häufig die gesamte Logik auf dem Client. Mit Stored Procedures können Sie
Teile der Logik auf den Server verlagern. Dieses Modell wird jedoch teilweise auch wieder in
Frage gestellt, nämlich durch das 3-Schichten-Modell. Bei diesem Modell wird die
Geschäftslogik (die z. B. definiert, in welcher Form auf die Kundentabelle zugegriffen werden
kann) in separaten Objekten definiert, die zentral auf einem Server im Netzwerk laufen und die
ausschließlich den Datenzugriff erledigen. Über DCOM, CORBA, .NET-Remoting, Webdienste
oder andere Techniken kann eine Anwendung ohne direkten Zugriff auf die Datenbank deren
Daten trotzdem über diese mittlere Schicht, die Geschäftslogik-Schicht bearbeiten. Bei diesem
Modell stellt sich dann allerdings die Frage, ob Stored Procedures eingesetzt werden oder nicht.
Aus Performancegründen ist die Entscheidung für Stored Procedures allerdings auch im 3Schichten-Modell häufig die richtige.
In einem VBA-Programm können Sie zum Aufruf einer Stored Procedure ein ADO-CommandObjekt verwenden. Den Namen der Prozedur übergeben Sie in der Eigenschaft CommandText.
Wenn Sie CommandType auf adCmdStoredProc setzen, wird die Ausführung ein wenig
beschleunigt. Sie benötigen eine Verbindung zu der Datenbank, die Sie vor der Ausführung
über ein Connection-Objekt öffnen müssen und in die Eigenschaft ActiveConnection
schreiben. Wenn die Prozedur Parameter besitzt, müssen Sie diese entweder über die
CreateParameter-Methode des Command-Objekts erzeugen und dabei gleich der
Parameters-Auflistung mit deren Append-Methode anhängen, oder Sie erzeugen ein
separates Parameter-Objekt, setzen dessen Eigenschaften und hängen dies der Parameters-
Sichten, Stored Procedures, Funktionen und Trigger 77
Auflistung an. In beiden Varianten müssen Sie verschiedene Einstellungen vornehmen, die am
Beispiel der CreateParameter-Methode beschrieben werden:
Set Parameter = command.CreateParameter( _
[Name] [, Type] [, Direction,] [, Size] [, Value])
Name ist der Objektname. Type spezifiziert den Typ des Parameters. Sie können die folgenden
Konstanten einsetzen (nur die wichtigsten werden hier aufgelistet; in der ADO-Dokumentation,
die mit den MDAC-Komponenten installiert wird, finden Sie unter der Type-Eigenschaft alle
Konstanten):
Konstante
Bedeutung (Datenbank-Typkonstante in Klammern)
adBigInt
8 Byte Integer mit Vorzeichen (DBTYPE_I8).
adBinary
Binärer Wert (DBTYPE_BYTES).
adBoolean
Boolescher Wert (DBTYPE_BOOL).
adByRef
wird über OR mit einer anderen Konstanten verknüpft, um
festzulegen, dass der Parameter ein Zeiger auf den anderen Datentyp
ist (DBTYPE_BYREF).
adBSTR
Nullterminierter Unicode-String (DBTYPE_BSTR).
adChar
String (DBTYPE_STR).
adCurrency
8 Byte-Währungswert (DBTYPE_CY).
adDate
Date-Wert (DBTYPE_DATE). Wird verwaltet wie in Visual Basic
(Ganzzahlanteil stellt die Anzahl der Tage seit dem 30.12.1899 dar,
Nachkommaanteil die Sekunden)
adDBDate
Datumswert im Format yyyymmdd (DBTYPE_DBDATE).
adDBTime
Zeitwert im Format hhmmss (DBTYPE_DBTIME).
adDouble
Double-Wert (DBTYPE_R8).
adEmpty
definiert, dass kein Wert übergeben wird (DBTYPE_EMPTY).
adInteger
4 Byte Integer mit Vorzeichen (DBTYPE_I4).
adIUnknown
Vorsicht: Hiermit ist nicht gemeint, dass der Datentyp unbekannt ist,
sondern dass es sich um einen Zeiger auf ein COM-Interface vom
Typ IUnknown handelt. (DBTYPE_IUNKNOWN).
adSingle
Single-Wert (DBTYPE_R4).
adSmallInt
2 Byte Integer mit Vorzeichen (DBTYPE_I2).
adTinyInt
1 Byte Integer mit Vorzeichen (DBTYPE_I1).
adUnsignedBigInt
8 Byte Integer ohne Vorzeichen (DBTYPE_UI8).
adUnsignedInt
4 Byte Integer ohne Vorzeichen (DBTYPE_UI4).
adUnsignedSmallInt
2 Byte Integer ohne Vorzeichen (DBTYPE_UI2).
adUnsignedTinyInt
1 Byte Integer ohne Vorzeichen (DBTYPE_UI1).
adUserDefined
Benutzerdefinierter Typ (Zeiger auf eine Struktur) (DBTYPE_UDT).
adVarBinary
Binärwert, der in der Datenbank mit variabler Größe gespeichert
wird.
adVarChar
String, der in der Datenbank mit variabler Größe gespeichert wird..
Sichten, Stored Procedures, Funktionen und Trigger 78
adVariant
Variant-Wert (DBTYPE_VARIANT).
adVarWChar
Nullterminierter Unicode-String, der in der Datenbank mit variabler
Größe gespeichert wird.
adWChar
Nullterminierter Unicode-String (DBTYPE_WSTR).
Tabelle 11: ADO-Datentypen um Vergleich zu den SQL-Server-Datentypen
Direction sagt aus, ob der Parameter einen Wert in die Prozedur schreibt oder die Prozedur
einen Wert im Parameter zurückgibt oder beides:
Konstante
Bedeutung
adParamInput
Default: Der Parameter wird in die Stored Procedure geschrieben.
adParamOutput
Der Parameter wird von der Gespeicherten Prozedur gesetzt.
adParamInputOutput
Der Parameter wird in die Prozedur geschrieben und von der
Prozedur gesetzt.
adParamReturnValue
Diesen Wert geben Sie für den ersten Parameter der ParametersAuflistung an, wenn die Prozedur eine Funktion ist, die einen Wert
zurückgibt.
Tabelle 12: ADO-Konstanten für Parameter-Richtungen
Sie müssen die korrekte, in der gespeicherten Prozedur definierte Einstellung für
Direction angeben, da beim Aufruf der Stored Procedure ansonsten entweder die
Daten inkorrekt oder gar nicht übergeben werden oder ein Laufzeitfehler erzeugt
wird.
Size bestimmt die maximale Größe eines Parameter mit Daten variabler Länge. Wenn Sie bei
diesen Daten die Maximallänge nicht angeben, wird beim Anhängen des Parameter-Objekts
an die Parameters-Auflistung oft ein Laufzeitfehler erzeugt. Der Grund liegt darin, dass ADO
für Parameter mit variabler Länge soviel Speicherplatz reserviert, wie der Datentyp potentiell
benötigt, was jedoch zu wenig sei kann.
+ ,
%
Wenn eine Stored Procedure eine Funktion ist, also einen Wert zurückgibt, müssen Sie den
Parameters(0)
mit
ersten
Parameter
der
Parameters-Auflistung
Direction=adParamReturnValue versehen. Dieser Parameter enthält nach der Ausführung der
Prozedur den Rückgabewert. Lassen Sie sich nicht verwirren: Eine Gespeicherte Prozedur kann
einen Rückgabewert besitzen und/oder ein Recordset-Objekt erzeugen. Das Recordset-Objekt
wird von der Execute-Methode des Command-Objekts zurückgegeben.
Wenn alle Parameter angehangen sind, führen Sie die Prozedur mit der Execute-Methode aus.
Für Prozeduren, die Recordsets erzeugen, gilt:
Set Recordset = command.Execute([RecordsAffected] [,Parameters] [,Options])
Für Prozeduren, die keine Recordsets erzeugen, gilt:
command.Execute [RecordsAffected] [,Parameters] [,Options]
In RecordsAffected können Sie eine Long-Variable einsetzen, in der nach der Ausführung die
Anzahl der betroffenen Datensätze gespeichert ist. In Parameters können Sie alternativ zum
Anhängen der Parameter an deren Kollektion Parameter in einem Variant-Array übergeben.
Diese Variante hat jedoch den Nachteil, dass Rückgabewerte ignoriert werden. Options definiert
Sichten, Stored Procedures, Funktionen und Trigger 79
den Typ des Befehls und sollte hier auf adCmdStoredProc gesetzt werden. Alternativ können
Sie die Eigenschaft CommandType verwenden.
#
Aufruf der Prozedur byroyalty in der Pubs-Datenbank des Microsoft SQL Server, die
ermittelt, welche Autoren mit dem übergebenen Prozentwert an den Tantiemen ihrer Bücher
beteiligt sind:
Dim cmd As ADODB.Command, conn As ADODB.Connection
Dim rst As ADODB.Recordset
Set cmd = New ADODB.Command
Set conn = New ADODB.Connection
conn.Open "PROVIDER=MSDASQL;DSN=Pubs;UID=sa;PWD=honda"
cmd.CommandText = "byroyalty" ' Name der Gespeicherten Prozedur
cmd.CommandType = adCmdStoredProc ' Typ des Befehls
Set cmd.ActiveConnection = conn ' Verbindung für die Ausführung
' Parameter erzeugen und direkt anhängen
cmd.Parameters.Append cmd.CreateParameter("", adInteger, _
adParamInput, 2, 50)
Set rst = cmd.Execute
While Not rst.EOF
List1.AddItem rst.Fields(0).Value
rst.MoveNext
Wend
rst.Close
A/9
0
*
Innerhalb von Stored Procedures können Sie globale Variablen verwenden. Globale Variablen
erkennen Sie an einem doppelten @. Im Folgenden finden Sie eine Auswahl der wichtigsten
Variablen:
Variable
Bedeutung
@@CONNECTIONS
Die Anzahl der aktuellen und der versuchten Logins seit dem Start
des SQL Servers
@@ERROR
Der letzte vom System erzeugte Fehler. Verwenden Sie @@ERROR,
um den Fehlerstatus der zuletzt ausgeführten Anweisung zu
ermitteln. Sie können den Fehler mit RAISERROR auch an den
Benutzer weitergeben.
@@FETCH_STATUS
Der Status des letzten Fetch bei der Verwendung von Cursorn
(siehe unten)
@@ROWCOUNT
Die Anzahl der von der letzten Anweisung betroffenen Zeilen.
Wird von nahezu jeder Anweisung gesetzt, weswegen Sie das
unten beschriebene beachten sollten.
@@SERVERNAME
Der Name des SQL Servers
@@TRANCOUNT
Die Anzahl der momentan aktiven Transaktionen für den aktuellen
Benutzer
@@VERSION
Die Versionsnummer des SQL Servers
Tabelle 13: Wichtige globale Variablen des SQL Servers
Beachten Sie bei @@ROWCOUNT, dass eigentlich jede Anweisung (nicht nur SQLAnweisungen) @@ROWCOUNT setzt. Idiotischerweise macht dies sogar die IFAnweisung. Statt
Sichten, Stored Procedures, Funktionen und Trigger 80
UPDATE Artikel SET Preis = Preis * .01
IF @@ROWCOUNT > 0
BEGIN
/* Anweisungen */
END
müssen Sie den folgenden Programmcode verwenden:
DELARE @RowCount int
UPDATE Artikel SET Preis = Preis * .01
SELECT @RowCount = @@ROWCOUNT
IF @RowCount > 0
BEGIN
/* Anweisungen */
END
A/:
5$- 1
TSQL bietet einige einfache Kontrollstrukturen zur Programmierung, wie die IF- und die
WHILE-Anweisung. Bei der Verwendung dieser Strukturen müssen Sie beachten, dass sich die
Anweisungen immer nur auf die nächste Zeile beziehen, wenn sie keine Blöcke verwenden. Ein
Block wird eingeleitet durch das Schlüsselworte BEGIN und beendet durch das Schlüsselworte
END.
Die Syntax der IF-Abfrage sieht folgendermaßen aus:
IF Boolean_expression
{sql_statement | statement_block}
[ELSE
{sql_statement | statement_block}]
Die Syntax der WHILE- Schleife:
WHILE Boolean_expression
{sql_statement | statement_block}
[BREAK]
{sql_statement | statement_block}
[CONTINUE]
Mit BREAK können Sie eine WHILE-Schleife abbrechen, mit CONTINUE können Sie außerhalb
der WHILE-Schleife diese wieder neu starten.
Einfaches Beispiel für WHILE und IF:
DECLARE @Counter int
SET @Counter = 0
WHILE @Counter < 10
BEGIN
IF @Counter = 5
BEGIN
PRINT "Zähler ist 5"
END
ELSE
BEGIN
PRINT "Zähler ist nicht 5"
END
SET @Counter = @Counter + 1
END
In diesem Beispiel wird die PRINT-Anweisung verwendet, um Testausgaben im Query
Analyzer zu erzeugen.
Sinnvolles Beispiel: Erhöhen des Artikelpreises um je 10%, solange, bis entweder der
durchschnittliche Preis größer/gleich 30 ist oder der höchste Preis größer als 300:
WHILE (SELECT AVG(UnitPrice) FROM Products) < 30
BEGIN
Sichten, Stored Procedures, Funktionen und Trigger 81
UPDATE Products SET UnitPrice = UnitPrice * 1.1
IF (SELECT MAX(UnitPrice) FROM Products) > 300 BREAK
END
Wie Sie in diesem Beispiel sehen, können Sie eine Abfrage, die einen Wert zurückgibt, auch in
Ausdrücken verwenden.
Zur Strukturierung ihres Programms können sie zudem die CASE-Anweisung verwenden, die in
zwei Varianten vorliegt:
Variante 1:
CASE input_expression
WHEN when_expression THEN
result_expression
[...n]
[ELSE
else_result_expression]
END
Diese Variante von CASE entspricht im Wesentlichen dem Case von VBA. Der in
input_expression übergebene Wert wird mit den in when_expression übergebenen Werten
verglichen. Wenn ein Vergleich wahr wird, wird der in result_expression übergebene Wert
allerdings von CASE wie ein Funktionsrückgabewert zurückgegeben.
Beispiel:
DECLARE @Counter int
SET @Counter = 0
WHILE @Counter < 10
BEGIN
PRINT CASE @Counter
WHEN 1 THEN "Zähler ist 1"
WHEN 2 THEN "Zähler ist 2"
ELSE "Zähler ist weder 1 noch 2"
END
SET @Counter = @Counter + 1
END
Variante 2:
CASE
WHEN Boolean_expression THEN result_expression
[...n]
[ELSE else_result_expression]
END
Diese Version von CASE arbeitet ähnlich der ersten Variante, nur dass im WHEN-Block ein
Vergleichsausdruck verwendet wird.
Sichten, Stored Procedures, Funktionen und Trigger 82
A/@
5$-
#
TSQL kennt natürlich auch die gängigen Operatoren, die ich hier nur kurz beschreibe. Für
nähere Informationen lesen Sie gegebenenfalls in der TSQL-Hilfe nach.
C %
,
#
Operator
Bedeutung
=
Zuweisung
+
Addition von Zahlen oder Zeichenketten
-
Subtraktion
*
Multiplikation
/
Division
%
Restwert-Division
Tabelle 14: Die TSQL-Zuweisungs- und die arithmetischen Operatoren
*
,
#
Operator
Bedeutung
=
Gleichheit
>
Größer
>=
Größer / Gleich
<
Kleiner
<=
Kleiner / Gleich
<> oder !=
Ungleich
!<
Nicht kleiner als
!>
Nicht größer als
Tabelle 15: Die TSQL-Vergleichs-Operatoren
,
#
Operator
Bedeutung
ALL
ergibt TRUE wenn der linke Operand in einer rechts angegebenen
Menge vorkommt. Die Menge wird in Klammern entweder als
kommabegrenzte Wertliste geschrieben oder über eine
Unterabfrage ermittelt.
AND
ergibt TRUE wenn zwei boolesche Ausdrücke TRUE ergeben.
ANY
ergibt TRUE wenn mindestens ein Vergleiche in einer Menge TRUE
ergibt.
BETWEEN x AND y
ergibt TRUE wenn der Wert des linken Operanden zwischen x und y
liegt.
EXISTS
ergibt TRUE wenn eine rechts angegebene Unterabfrage mindestens
einen Datensatz ergibt.
Sichten, Stored Procedures, Funktionen und Trigger 83
IN
ergibt TRUE wenn der linke Operand in der rechts in Klammern
angegebenen Menge liegt.
LIKE
ergibt TRUE wenn der linke Operand dem rechts angegebenen
Zeichenkettenmuster (inklusive Wildcards) entspricht.
NOT
kehrt den Wert eines booleschen Ausdrucks um.
OR
ergibt TRUE wenn einer von zwei booleschen Ausdrücken TRUE
ergibt.
SOME
wie All
Tabelle 16: Die logischen TSQL-Operatoren
A/A
$
,
&
Häufig reicht innerhalb einer Stored Procedure eine einfache SELECT-Anweisung nicht aus.
Dann können Sie einen Cursor verwenden, um zeilenweise durch die ermittelten Datensätze zu
gehen.
Sie deklarieren einen Cursor mit
DECLARE cursor_name CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE [OF column_name [,...n]]]
cursor_name definiert den Namen des Cursors. Mit dem Zusatz GLOBAL erreichen Sie, dass der
Cursor auch von anderen Prozeduren verwendet werden kann (was allerdings nur für die
Verbindung zum Server gilt, die die Prozedur aufgerufen hat). Mit FORWARD_ONLY definieren
Sie, dass die Datensatzliste nur einmal vorwärts durchlaufen werden kann. Ein solcher Cursor
benötigt weniger Systemressourcen. Mit STATIC | KEYSET | DYNAMIC | FAST_FORWARD geben
Sie den Typ des Cursors an. Dieser entspricht im Wesentlichen den Cursortypen von ADO. Mit
READ_ONLY | SCROLL_LOCKS | OPTIMISTIC geben Sie für Aktualisierungen an, wie Sie Ihre
Datensatzliste sperren wollen. Die UPDATE-Optionen legt fest, ob er Cursor eine Aktualisierung
zulässt. Sie können die aktualisierbaren Datenfelder mit UPDATE OF column_name
einschränken.
Normalerweise benötigen Sie wahrscheinlich seltener einen Cursor, der aktualisierbar ist. Sie
sollten diese Möglichkeit jedoch im Auge behalten.
Ein Cursor zum einfachen, schreibgeschützten Durchgehen der Customers-Tabelle wird z. B.
folgendermaßen definiert:
DECLARE curCustomers CURSOR
LOCAL
FORWARD_ONLY
STATIC
READ_ONLY
FOR SELECT CustomerID, CompanyName
FROM Customers
ORDER BY CustomerID
Nachdem Sie den Cursor erzeugt haben, müssen Sie diesen noch öffnen:
OPEN curCustomers
Nach dem Öffnen können Sie die Datensätze mit FETCH durchgehen:
Sichten, Stored Procedures, Funktionen und Trigger 84
FETCH
[[NEXT | PRIOR | FIRST | LAST | ABSOLUTE {n | @nvar}| RELATIVE {n | @nvar}]
FROM]
{{[GLOBAL] cursor_name } | @cursor_variable_name}
[INTO @variable_name[,...n] ]
FETCH geht zum nächsten (FETCH NEXT), vorherigen (FETCH PRIOR), ersten (FETCH FIRST),
letzten (FETCH LAST) oder zu einem Datensatz mit einer bestimmten Nummer (FETCH
ABSOLUTE 10 z. B. zum 10. Datensatz) oder zu einem Datensatz relativ zum aktuellen (FETCH
RELATIVE 5 z. B. 5 Datensätze weiter),
Mit INTO @variable_name sorgen Sie dafür, dass die Datenfelder in Variablen geschrieben
werden (die Sie natürlich zuvor deklarieren müssen).
Um eine Datensatzliste durchzugehen, hilft Ihnen die globale Variable @@FETCH_STATUS.
Diese nimmt nach einem FETCH die folgenden Werte an:
@@FETCH_STATUS-Wert Bedeutung
0
Der letzte Fetch war erfolgreich.
-1
Der letzte Fetch war nicht erfolgreich, da die Datensatzliste vor
dem ersten oder nach dem letzten Datensatz steht. Es ist kein
Datensatz aktuell.
-2
Der letzte Fetch war nicht erfolgreich, da der aktuelle Datensatz
(von einem anderen Benutzer) zwischenzeitlich gelöscht wurde.
Tabelle 17: Werte des Fetch-Status
Nach dem Auswerten schließen Sie den Cursor und geben den reservierten Speicher frei:
CLOSE curCustomers
DEALLOCATE curCustomers
Das folgende Beispiel zeigt einen einfachen Fetch. Dabei wird die nächsten freie KundenNummer in einer Kunden-Tabelle ermittelt, deren Kunden-Nummer nicht automatisch (über
eine Identity-Spalte) vergeben wird:
CREATE PROCEDURE Get_Free_CustomerId(@StartId int) AS
DECLARE @CustomerId int
DECLARE @SearchId int
SELECT @SearchId = @StartId
DECLARE curCustomers CURSOR
LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR SELECT CustomerID FROM Customers
WHERE CustomerID > @StartId ORDER BY CustomerID
OPEN curCustomers
FETCH NEXT FROM curCustomers INTO @CustomerID
WHILE @@FETCH_STATUS = 0
BEGIN
IF @CustomerID > @SearchId
BEGIN
CLOSE curCustomers
DEALLOCATE curCustomers
RETURN @SearchID
END
FETCH NEXT FROM curCustomers INTO @CustomerID
SET @SearchId = @SearchId + 1
END
CLOSE curCustomers
DEALLOCATE curCustomers
RETURN @SearchId
Sichten, Stored Procedures, Funktionen und Trigger 85
A/D
$
,
4
Stored Procedures können Sie wie Sichten sehr einfach über die ALTER-Anweisung verändern:
ALTER PROCEDURE Get_Free_CustomerId(@StartId int) AS
...
Wie schon bei Sichten ist der Vorteil dabei, dass der SQL Server Rechte, die auf die Stored
Procedure gesetzt sind, beibehält.
A8 2
Ab der Version 2000 erlaubt der SQL Server (endlich) auch die Erstellung von Funktionen.
Funktionen, die ebenfalls in TSQL geschrieben werden, sind so etwas wie vereinfachte Stored
Procedures, die aber im Gegensatz zu diesen beliebige Datentypen zurückgeben können. Einer
Funktion können Argumente übergeben werden. SQL-Server-Funktionen gleichen damit den
von der herkömmlichen Programmierung bekannten Funktionen.
Funktionen können im SQL Server einfache Datentypen oder Datensatzlisten (in Form des
table-Datentyps) zurückgeben. Da die Anwendung von Funktionen, die Datensatzlisten
zurückgeben, eher speziell ist, verzichte ich in diesem Artikel auf eine nähere Beschreibung.
A8
2
Funktionen können Sie ähnlich Stored Procedures über den FUNKTIONEN-Eintrag im
Datenbank-Ordner des Enterprise Managers erstellen. Alternativ können Sie Funktionen auch
direkt in SQL schreiben (was ja auch bei der Erstellung im Enterprise Manager notwendig ist).
Funktionen, die einen einfachen Datentypen zurückgeben, werden nach dem folgenden Schema
deklariert:
CREATE FUNCTION [owner_name.]function_name
([{@parameter_name [AS] scalar_parameter_data_type [ = default ] } [ ,...n ]
] )
RETURNS scalar_return_data_type
[ WITH < function_option> [ [,] ...n] ]
[ AS ]
BEGIN
function_body
RETURN scalar_expression
END
Bei der Deklaration müssen Sie angeben, welche Argumente die Funktion besitzt und welchen
Datentyp diese zurückliefert. Innerhalb der Funktion können Sie mit TSQL programmieren. Am
Ende der Funktion geben Sie das Ergebnis mit RETURN zurück.
Sichten, Stored Procedures, Funktionen und Trigger 86
So können Sie z. B. in der Northwind-Datenbank eine Funktion schreiben, die den
Gesamtumsatz eines Kunden ermittelt und zurückgibt:
CREATE FUNCTION GetCustomerSales(@CustomerId nvarchar(5))
RETURNS money
AS
BEGIN
/* Variable für den Umsatz */
DECLARE @Sales money
/* Abfrage der Umsatzdaten */
SELECT @Sales = SUM([Order Details].UnitPrice * [Order Details].Quantity)
FROM [Order Details] INNER JOIN Orders
ON [Order Details].OrderId = Orders.OrderId
WHERE Orders.CustomerId = @CustomerId
/* Rückgabe */
RETURN @Sales
END
Diese Funktion können Sie nun in jeder SQL-Anweisung einsetzen. Als Argument können Sie
konstante Daten, Variablen oder auch die Inhalte von Tabellenfeldern übergeben. Lediglich der
Datentyp der übergebenen Daten muss zum Argument passen. Den Rückgabewert können Sie in
SELECT-Abfragen ausgeben oder in Variablen speichern.
Das folgende Beispiel ruft die Funktion für einen spezifischen Kunden auf:
SELECT dbo.GetCustomerSales('ALFKI') AS Sales
Beachten Sie, dass Sie beim Aufruf von Funktionen den Besitzer immer mit
angeben müssen.
Das Ergebnis ist eine einfache Datensatzliste mit einem Datensatz und einer Spalte Sales:
Sales
--------------------4596.2000
Das nächste Beispiel fragt einige Kundendaten ab und verwendet die Funktion zur Ermittlung
des Umsatzes des jeweiligen Kunden:
SELECT CustomerId, CompanyName, City, dbo.GetCustomerSales(CustomerId) AS
Sales
FROM Customers
Das Ergebnis (Auszug):
CustomerId
---------ALFKI
ANATR
ANTON
...
WILMK
WOLZA
A8"
CompanyName
---------------------------------------Alfreds Futterkiste
Ana Trujillo Emparedados y helados
Antonio Moreno Taquería
City
--------------Berlin
México D.F.
México D.F.
Sales
---------4596.2000
1402.9500
7515.3500
Wilman Kala
Wolski Zajazd
Helsinki
Warszawa
3161.3500
3531.9500
2
4
Funktionen können Sie ähnlich Stored Procedures und Sichten über die ALTER-Anweisung
verändern:
ALTER FUNCTION GetCustomerSales(@CustomerId nvarchar(5))
RETURNS money
AS
...
Sichten, Stored Procedures, Funktionen und Trigger 87
A9 5
Trigger ähneln auch wieder Stored Procedures. Sie sind wie diese in TSQL geschrieben und
verwenden dieselben Programmstrukturen. Die Unterschied sind, dass Trigger keine Parameter
besitzen können und keine Werte zurückgeben, und dass Trigger nicht explizit aufgerufen
werden, sondern implizit immer dann, wenn auf einer Tabelle Datensätze angefügt, geändert
oder gelöscht werden.
Ein Trigger ist immer fest mit einer Tabelle verbunden und bezieht sich dort auf eine UPDATE-,
INSERT- oder DELETE-Aktion oder eine Kombination dieser Aktionen.
Trigger werden verwendet, um:
•
referentielle Integrität da zu gewährleisten, wo die eingebaute Referentielle Integrität des
SQL Servers nicht ausreicht;
•
Spalten mit laufenden Summen zu aktualisieren;
•
Spalten zu aktualisieren, die berechnete Werte beinhalten;
•
externe Vorgänge anzustoßen, wie zum Beispiel das Senden einer E-Mail bei einer
bestimmten Aktion.
Auf einer Tabelle können mehrere Trigger für eine bestimmte Aktion (INSERT, UPDATE oder
DELETE) definiert werden. Dabei müssen Sie beachten, dass die Reihenfolge dieser Trigger
nicht festgelegt werden kann.
A9
5
Einen Trigger erzeugen Sie im Enterprise Manager über das Kontextmenü einer Tabelle über
den Befehl ALLE TASKS / TRIGGER VERWALTEN:
Abbildung 39: Der Dialog zur Verwaltung von Triggern mit einem neuen Trigger auf der Kunden-Tabelle
Sichten, Stored Procedures, Funktionen und Trigger 88
A9"
,
5
In einem Trigger stehen ihnen die speziellen logischen Tabellen inserted und deleted zur
Verfügung. inserted enthält bei einem Anfüge-Trigger alle angefügten Datensätze und bei
einem Aktualisierungs-Trigger alle geänderten Datensätze in dem Zustand nach der Änderung.
deleted enthält bei einem Lösch-Trigger alle gelöschten Datensätze und bei einem
Aktualisierungs-Trigger alle geänderten Datensätze vor der Änderung. Diese beiden Tabellen
können in Abfragen genauso verwendet werden wie normale Tabellen mit dem Unterschied,
dass eine Aktualisierung dieser Tabellen nicht möglich ist.
5
Das folgende Beispiel implementiert einen Trigger, der beim Anfügen eines Bestelldetails das
(neue) Feld Order Sum der Bestellung aktualisiert.
Ein solches Feld, das immer die Gesamt-Summe der Bestellung speichern soll, ist
natürlich redundant und widerspricht den Regeln der Normalisierung. Die
Gesamtsumme einer Bestellung kann schließlich auch über eine Abfrage der
Bestelldetails ermittelt werden. In großen Datenbanken führt der dazu notwendige
Join inklusive der eventuell notwendigen Gruppierung aber zu einer sehr
schlechten Performance. Die Verwaltung der Bestell-Gesamtsumme im separaten
Feld bringt also in vielen Fällen eine erhebliche Performance-Steigerung. Und das
ist das, was den Endanwender interessiert. Die Trigger, die wir hier entwickeln,
kümmern sich um das automatische Aktualisieren. Das redundante Feld führt also
zu keinerlei Pflege-Aufwand.
Um dieses Beispiel nachvollziehen zu können, müssen Sie der Tabelle Orders in der
Northwind-Datenbank zunächst das Feld Order Sum hinzufügen:
ALTER TABLE Orders
ADD [Order Sum] money NOT NULL DEFAULT 0
Dann können Sie den Trigger erzeugen:
CREATE TRIGGER Order_Details_I_Trig ON [Order Details]
FOR INSERT AS
/* Variable für die Summe */
DECLARE @Sum money
/* Summe der neuen Bestelldetails ermitteln (das können
in einem Trigger beim Hinzufügen durchaus auch mehrere
sein, z. B. wenn Bestelldetails über die Abfrage einer
anderen Tabelle hinzugefügt wurden) */
SELECT @Sum = Sum(UnitPrice * Quantity) FROM inserted
/* Summe in der Bestellung ablegen. Dazu wird zunächst die
Bestellnummer ermittelt */
DECLARE @OrderId int
SELECT @OrderId = OrderId FROM inserted
/* Summe speichern */
UPDATE Orders SET [Order Sum] = [Order Sum] + @Sum
WHERE OrderId = @OrderId
Der Trigger ist allerdings nicht perfekt. Wenn über eine SELECT-INTO-Anweisung
mehrere Bestelldetails aus einer anderen Tabelle heraus in die Tabelle Order
Details geschrieben werden und diese unterschiedlichen Bestellungen angehören,
wird deren Gesamtsumme lediglich in eine der Bestellungen geschrieben.
Sichten, Stored Procedures, Funktionen und Trigger 89
Dieses Problem zu lösen ist nicht einfach. Sie können die inserted-Tabelle über einen Cursor
Datensatz für Datensatz durchgehen um jede einzelne Bestellung zu aktualisieren:
CREATE TRIGGER Order_Details_I_Trig ON [Order Details]
FOR INSERT AS
/* inserted-Tabelle über einen Cursor Datensatz für Datensatz durchgehen */
DECLARE cur CURSOR
LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR SELECT OrderId, UnitPrice, Quantity
FROM inserted
OPEN cur
/* Variablen für die Bestellnummer und die
Summe der Detailbestellung */
DECLARE @OrderId nvarchar(5)
DECLARE @UnitPrice money
DECLARE @Quantity int
/* Cursor durchgehen */
FETCH NEXT FROM cur INTO @OrderId, @UnitPrice, @Quantity
WHILE @@FETCH_STATUS = 0
BEGIN
/* Summe in der Bestellung ablegen */
UPDATE Orders SET [Order Sum] = [Order Sum] + (@UnitPrice * @Quantity)
WHERE OrderId = @OrderId
/* Nächste Position */
FETCH NEXT FROM cur INTO @OrderId, @UnitPrice, @Quantity
END
Dieser Trigger aktualisiert nun bei jedem Hinzufügen eines Bestelldetails die Gesamtsumme in
der Bestellung. Das folgende Beispiel erstellt eine neue Bestellung und fragt am Ende die
Bestellsumme ab:
/* Bestellung hinzufügen */
INSERT INTO Orders (CustomerId, OrderDate)
VALUES ('ALFKI', GETDATE())
/* Die automatisch erzeugte OrderId ermitteln */
DECLARE @OrderId int
SELECT @OrderId = MAX(OrderId) FROM Orders
/* Bestelldetails hinzufügen */
DECLARE @ProductId int
DECLARE @UnitPrice money
DECLARE @Quantity int
SET @ProductId = 1
SET @Quantity = 100
SELECT @UnitPrice = UnitPrice FROM Products WHERE ProductId = @ProductId
INSERT INTO [Order Details] (OrderId, ProductId, UnitPrice, Quantity)
VALUES (@OrderId, @ProductId, @UnitPrice, @Quantity)
SET @ProductId = 2
SET @Quantity = 10
SELECT @UnitPrice = UnitPrice FROM Products WHERE ProductId = @ProductId
INSERT INTO [Order Details] (OrderId, ProductId, UnitPrice, Quantity)
VALUES (@OrderId, @ProductId, @UnitPrice, @Quantity)
SET @ProductId = 3
SET @Quantity = 55
SELECT @UnitPrice = UnitPrice FROM Products WHERE ProductId = @ProductId
INSERT INTO [Order Details] (OrderId, ProductId, UnitPrice, Quantity)
VALUES (@OrderId, @ProductId, @UnitPrice, @Quantity)
/* Bestellung abfragen */
SELECT OrderId, [Order Sum] FROM orders WHERE orderId = @OrderId
Sichten, Stored Procedures, Funktionen und Trigger 90
5
Nun müssen Sie noch einen Trigger implementieren, der auf ein Aktualisieren der für die
Berechnung wichtigen Spalten reagiert. Dieser Trigger fragt die Tabelle inserted nach den
neuen Daten und die Tabelle deleted nach den alten Daten ab um den neuen Bestellwert
korrekt ermitteln zu können.
In Aktualisierungs-Triggern ist es oft notwendig, zu erkennen, welche Spalten aktualisiert
wurden. So muss ein Trigger, der die Aktualisierung der Primärschlüsselspalte in einer
Mastertabelle an alle in Beziehung stehenden Detailtabellen weitergibt, erkennen, ob die
Primärschlüsselspalte geändert wurde. Sie können dies sehr einfach über die UPDATE-Funktion
ermitteln, wie Sie im Beispiel sehen:
CREATE TRIGGER Order_Details_U_Trig ON [Order Details]
FOR UPDATE AS
IF UPDATE(UnitPrice) OR UPDATE(Quantity)
/* Wenn überhaupt eine der relevanten Spalten geändert wurde */
BEGIN
/* inserted-Tabelle über einen Cursor Datensatz für Datensatz durchgehen */
DECLARE cur CURSOR
LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR SELECT OrderId, ProductId, UnitPrice * Quantity AS DetailSum
FROM inserted
OPEN cur
/* Variablen für die Bestellnummer und die Summe der Detailbestellung */
DECLARE @OrderId nvarchar(5)
DECLARE @ProductId int
DECLARE @SumNew money
DECLARE @SumOld money
/* Cursor durchgehen */
FETCH NEXT FROM cur INTO @OrderId, @ProductId, @SumNew
WHILE @@FETCH_STATUS = 0
BEGIN
/* Ermitteln des alten Werts aus der deleted-Tabelle */
SELECT @SumOld = UnitPrice * Quantity FROM deleted
WHERE OrderId = @OrderId AND ProductId = @ProductId
/* Summe in der Bestellung aktualisieren */
UPDATE Orders SET [Order Sum] = [Order Sum] - @SumOld + @SumNew
WHERE OrderId = @OrderId
/* Nächste Position */
FETCH NEXT FROM cur INTO @OrderId, @ProductId, @SumNew
END
END
Nun können Sie ohne Probleme auch Bestelldetails aktualisieren. Die Bestellsumme wird
automatisch aktualisiert:
UPDATE [Order Details] SET UnitPrice = UnitPrice * 0.9 WHERE OrderId = 1001
Sichten, Stored Procedures, Funktionen und Trigger 91
=, 5
In unserem Beispiel müssen Sie natürlich noch auf das Löschen von Bestelldetails reagieren.
Dazu implementieren Sie einen Lösch-Trigger, der die deleted-Tabelle durchgeht und die
darin enthaltene Bestellsumme von der Gesamt-Bestellsumme abzieht:
CREATE TRIGGER Order_Details_D_Trig ON [Order Details]
FOR DELETE AS
/* deleted-Tabelle über einen Cursor Datensatz für Datensatz durchgehen */
DECLARE cur CURSOR
LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR SELECT OrderId, UnitPrice * Quantity AS DetailSum
FROM deleted
OPEN cur
/* Variablen für die Bestellnummer und die Summe der Detailbestellung */
DECLARE @OrderId nvarchar(5)
DECLARE @Sum money
/* Cursor durchgehen */
FETCH NEXT FROM cur INTO @OrderId, @Sum
WHILE @@FETCH_STATUS = 0
BEGIN
/* Summe in der Bestellung aktualisieren */
UPDATE Orders SET [Order Sum] = [Order Sum] - @Sum
WHERE OrderId = @OrderId
/* Nächste Position */
FETCH NEXT FROM cur INTO @OrderId, @Sum
END
Nun müsste die Bestellsumme, die in den Bestellungen verwaltet wird, immer korrekt sein. Vor
den Triggern bereits vorhandene Bestellungen müssen Sie allerdings noch »von Hand«
aktualisieren. Dabei müssen Sie beachten, dass eine Bestellung auch keine Bestelldetails
besitzen kann. Ich löse das Problem über eine Unterabfrage und die ISNULL-Funktion:
UPDATE Orders SET [Order Sum] =
(SELECT ISNULL(SUM(UnitPrice * Quantity), 0) FROM [Order Details]
WHERE [Order Details].OrderId = Orders.OrderId)
5
5
Gerade bei Triggern, die ja immer automatisch aufgerufen werden, ist das Testen der Funktion
extrem wichtig. Bei unseren Beispieltriggern können Sie dazu einfach eine Bestellung erzeugen,
ändern und Bestelldetails wieder löschen, um die korrekte Funktion zu ermitteln:
/* Bestellung hinzufügen */
INSERT INTO Orders (CustomerId, OrderDate)
VALUES ('ALFKI', GETDATE())
/* Die automatisch erzeugte OrderId ermitteln */
DECLARE @OrderId int
SELECT @OrderId = MAX(OrderId) FROM Orders
/* Bestelldetails hinzufügen */
DECLARE @ProductId int
DECLARE @UnitPrice money
DECLARE @Quantity int
SET @ProductId = 1
SET @Quantity = 100
SELECT @UnitPrice = UnitPrice FROM Products WHERE ProductId = @ProductId
INSERT INTO [Order Details] (OrderId, ProductId, UnitPrice, Quantity)
VALUES (@OrderId, @ProductId, @UnitPrice, @Quantity)
Sichten, Stored Procedures, Funktionen und Trigger 92
SET @ProductId = 2
SET @Quantity = 10
SELECT @UnitPrice = UnitPrice FROM Products WHERE ProductId = @ProductId
INSERT INTO [Order Details] (OrderId, ProductId, UnitPrice, Quantity)
VALUES (@OrderId, @ProductId, @UnitPrice, @Quantity)
SET @ProductId = 3
SET @Quantity = 55
SELECT @UnitPrice = UnitPrice FROM Products WHERE ProductId = @ProductId
INSERT INTO [Order Details] (OrderId, ProductId, UnitPrice, Quantity)
VALUES (@OrderId, @ProductId, @UnitPrice, @Quantity)
/* Bestellung abfragen */
SELECT OrderId, [Order Sum] FROM Orders WHERE OrderId = @OrderId
/* Bestellung ändern */
UPDATE [Order Details] SET Quantity = 100
WHERE OrderId = @OrderId AND ProductId = 2
/* Bestellung abfragen */
SELECT OrderId, [Order Sum] FROM Orders WHERE OrderId = @OrderId
/* Ein Bestelldetail löschen */
DELETE FROM [Order Details] WHERE OrderId = @OrderId AND ProductId = 2
/* Bestellung abfragen */
SELECT OrderId, [Order Sum] FROM Orders WHERE OrderId = @OrderId
Wenn die Trigger korrekt ausgeführt werden, gibt die erste Abfrage nach dem Hinzufügen die
Summe 2540 zurück, die zweite (nach dem Ändern eines Bestelldetails) die Summe 4060 und
die dritte (nach dem Löschen eines Bestelldetails) die Summe 2728.
Wenn Ihre Trigger nicht zuverlässig arbeiten, müssen Sie wohl debuggen, wie ich es in Kapitel
8.6 beschreibe.
A9/
+
,
5
Ein Trigger wird immer nach der Aktion ausgelöst, die den Trigger aufgerufen hat. Bei einem
Lösch-Trigger zum Beispiel sind die Datensätze zum Zeitpunkt der Ausführung des Triggers
bereits gelöscht, wobei das Löschen allerdings in einer Transaktion ausgeführt wird. Dasselbe
gilt natürlich für Aktualisierungs- und Anfüge-Trigger. Innerhalb des Triggers können Sie die
Aktion, die den Trigger aufgerufen hat, durch ein einfaches ROLLBACK rückgängig machen.
Das folgende Beispiel implementiert einen Trigger, der eine Veränderung der Verleihe-Tabelle
am Ende eines Monats (wenn der Monatsbericht geschrieben wird) verhindert:
CREATE TRIGGER Verleihe_DIU_Trig ON Verleihe
FOR DELETE, INSERT, UPDATE AS
IF DAY(GETDATE()) >= 28
BEGIN
ROLLBACK
DECLARE @Error nvarchar(255)
SET @Error = 'Am Monatsende kann kein Verleih aufgenommen, ' +
'verändert oder gelöscht werden'
RAISERROR(@Error, 16, 1)
END
Dieses Beispiel verwendet die RAISERROR-Funktion zur Erzeugung eines
benutzerdefinierten Fehlers. Am ersten Argument wird der Fehlertext übergeben.
Im Beispiel wird eine Variable für den Fehlertext verwendet, weil TSQL das
Umbrechen eines Zeichenketten-Literals am ersten Argument der RAISERRORFunktion (eigenartigerweise) nicht unterstützt. Am zweiten Argument übergeben
Sie den Schweregrad (16 = „normaler“ Fehler, nicht kritisch) des Fehlers und am
dritten einen Statuswert.
Sichten, Stored Procedures, Funktionen und Trigger 93
A98
* 4
5
Trigger können Sie wie Stored Procedures, Sichten und Funktionen über die ALTER-Anweisung
verändern.
A:
$
5
2
,
7
Das Debuggen von Stored Procedures, Funktionen und Triggern ist ein wichtiger Prozess,
wenigstens dann, wenn diese Fehler beinhalten (was bei mir recht häufig der Fall ist ). Stored
Procedures, Funktionen und Trigger können Sie über verschiedene Debugger auf Fehler
untersuchen. Microsoft stellt für TSQL-Programme den TSQL-Debugger zur Verfügung, der
Bestandteil der SQL-Server-2000-Client-Tools und der Enterprise-Edition von Visual Studio 6
ist. Alternativ können Sie auch den Debugger von Visual Studio .NET verwenden. Im
Folgenden beschreibe ich, wie Sie den TSQL-Debugger und den Debugger von Visual Studio
.NET grundsätzlich einsetzen.
Sie sollten beim Debuggen beachten, dass Sie dieses nach Möglichkeit niemals in
einem SQL Server ausführen sollten, der in der Produktion eingesetzt wird. Beim
Debuggen wird der Server zum einen in einen speziellen Zustand versetzt, der das
Debuggen überhaupt erst ermöglicht und der den Server verlangsamt. Zum anderen
kann es immer vorkommen, dass der Debugging-Vorgang nicht korrekt
abgeschlossen und das System deshalb in der Folge nur sehr träge ausgeführt wird
oder sogar irgendwann abstürzt. Debuggen Sie wenn möglich immer mit einer
Kopie der Datenbank auf einem separaten SQL Server.
A:
0
*
Damit Sie debuggen können, müssen auf dem SQL Server dessen Debugging-Komponenten
installiert sein. Holen Sie dies gegebenenfalls über die SQL-Server-Installation nach, indem Sie
diese normal starten und im sechsten Schritt die Option wählen, dass Sie »eine vorhandene
Instanz von SQL Server aktualisieren« wollen. Übergehen Sie die nächsten zwei Schritte, geben
Sie bei der Auswahl der zu installierenden Komponenten unter ENTWICKLUNGSTOOLS die
DEBUGGERSCHNITTSTELLE an und schließen Sie die Installation ab.
!
E
Auf direktem Wege können Sie nur Stored Procedures debuggen. In einigen Debuggern führen
Sie diese dazu über den Debugger aus, andere Debugger wie der von Visual Studio .NET
erlauben darüber hinaus auch das Setzen von Haltepunkten, an denen der Debugger die
Prozedur automatisch anhält. Damit können Sie Stored Procedures auch dann debuggen, wenn
ein in Visual Studio .NET ausgeführtes Programm diese ausführt. Prinzipiell können Sie also
•
im Query Analyzer oder in Visual Studio debuggen, indem Sie eine Stored Procedure dort
über den Debugger direkt aufrufen,
•
in Visual Studio debuggen, indem Sie in einer Stored Procedure oder Funktion einen
Haltepunkt setzen und ein, ebenfalls in Visual Studio geöffnetes (Visual Basic-, C#- etc.)
Anwendungs-Projekt ausführen das die Stored Procedure oder die Funktion direkt oder
indirekt aufruft.
Sichten, Stored Procedures, Funktionen und Trigger 94
Wenn Sie im Query Analyzer oder in Visual Studio ohne Ausführung eines
Programms eine Funktion debuggen wollen, müssen Sie eine Dummy-Stored
Procedure schreiben, die diese Funktion aufruft und die Stored Procedure
ausführen. Über das im Debugger mögliche schrittweise Weitergehen können Sie
dann in die Funktion verzweigen.
Zum direkten Debuggen eines Triggers müssen Sie ebenfalls eine Dummy-Stored
Procedure schreiben. Diese muss irgendeine SQL-Aktion ausführen, die den
Trigger auslöst. Über das schrittweise Weitergehen in der Stored Procedure können
Sie dann wie bei einer Funktion in den Trigger verzweigen.
A:"
#
Als Beispiel zum Debugging verwende ich eine Funktion und eine Stored Procedure, die diese
Funktion aufruft. Die Funktion soll (weil mir einmal wieder nichts weiter einfällt ...) ermitteln
ob eine Zahl eine Primzahl ist. Die Stored Procedure soll alle Produkte einer anzugebenden
Kategorie durchgehen, deren Produktnummer eine Primzahl ist und den Preis dieser Produkte
um einen anzugebenden Prozentwert erhöhen. Das Beispiel ist zwar eigentlich sinnlos, aber zum
Debuggen recht gut geeignet. Die Funktion enthält einen Fehler (welcher das ist, soll das
Debuggen klären):
CREATE FUNCTION IsPrimeNumber(@Number int)
RETURNS bit
AS
BEGIN
DECLARE @Divisor int
SET @Divisor = 1
WHILE @Divisor < @Number
BEGIN
IF @Number % @Divisor = 0
BEGIN
/* Die Zahl lässt sich ohne Rest teilen und ist
folglich keine Primzahl */
RETURN 0
END
SET @Divisor = @Divisor + 1
END
/* Wenn die Funktion hier ankommt ist die Zahl keine Primzahl */
RETURN 1
END
Die Stored Procedure ruft die Funktion auf:
CREATE PROCEDURE Update_PrimeNumber_Product_Price
(@CategoryId int, @Factor real) AS
UPDATE Products SET UnitPrice = UnitPrice * @Factor
WHERE CategoryId = @CategoryId AND dbo.IsPrimeNumber(ProductId) = 1
Leider funktioniert die Stored Procedure nicht. Bei allen Tests wird kein Produkt aktualisiert.
Sie müssen also debuggen.
Sichten, Stored Procedures, Funktionen und Trigger 95
A:/
5$-
Den TSQL-Debugger können Sie sehr einfach über den Query Analyzer aufrufen. Öffnen Sie
dazu den Ordner GESPEICHERTE PROZEDUREN für die Datenbank im Query Analyzer.
Abbildung 40: Der Ordner für gespeicherte Prozeduren im Query Analyzer
Suchen Sie die Stored Procedure und wählen Sie im Kontextmenü des Eintrags den Befehl
DEBUGGEN. Im erscheinenden Dialog können Sie die Parameterwerte definieren und die
Prozedur starten.
Abbildung 41: Dialog zum Starten des Debuggers
Sichten, Stored Procedures, Funktionen und Trigger 96
Starten Sie die Prozedur dann über den AUSFÜHREN-Schalter. Der Debugger startet die
Prozedur und hält diese an der ersten Anweisung an.
Abbildung 42: Der Debugger hat die Prozedur gestartet und an der ersten Anweisung angehalten
Über F11 können Sie nun jede Anweisung einzeln ausführen. F11 springt dabei in untergeordnet
aufgerufene Funktionen oder Trigger hinein (was in unserem Fall gewünscht ist). Mit F10
könnten Sie eine Anweisung ausführen ohne dass der Debugger in untergeordnete Funktionen
oder Trigger springt. Wenn Sie nun F11 betätigen, springt der Debugger in die Funktion.
Sichten, Stored Procedures, Funktionen und Trigger 97
Abbildung 43: Der Debugger ist in die Funktion gesprungen
Hier können Sie wieder mit F11 und F10 weitergehen um die Funktion zu debuggen. Im unteren
Bereich zeigt der Debugger dabei immer die aktuellen Werte aller lokalen Variablen und der
Parameter, einige wichtige globale Variablen und die Aufrufliste an. So können Sie sehr schnell
herausfinden, wo der Fehler liegt. In unserem Fall erkennen Sie bei einem der Durchläufe, bei
dem eine ProductId > 2 übergeben wird, dass die Schleife inkorrekt läuft. Diese beginnt
nämlich bei 1 und nicht, wie es sein sollte, erst bei 2.
Wenn Sie den Fehler gefunden haben, führen Sie die Stored Procedure dann mit F5 zu Ende
aus, damit der Debugger diese wieder freigibt.
Dieser Schritt ist sehr wichtig, da das System ansonsten in vielen Fällen bei
weiteren Tests durcheinander gerät und »hängen bleibt« bzw. abstürzt, wenn der
Debugger eine oder mehrere Stored Procedures aktuell noch angehalten hat. Sie
sollten diesen Schritt auch ausführen, bevor Sie den Debugger schließen.
.
#
Der TSQL-Debugger erlaubt auch das Setzen von Haltepunkten. Betätigen Sie auf einer
Anweisung F9 um einen solchen zu setzen. Haltepunkte werden nur aktiv wenn eine Stored
Procedure gestartet wurde. Sie können diese aber verwenden, um das Programm ab der
aktuellen Stelle über F5 weiter bis zum Haltepunkt auszuführen und dort weiter zu debuggen.
Sichten, Stored Procedures, Funktionen und Trigger 98
A:8
*
$
3 5
Wenn Sie Visual Studio .NET besitzen, können Sie den Debugger dieser
Entwicklungsumgebung zum einen verwenden um Stored Procedures, Funktionen und Trigger
wie im Query Analyzer direkt zu debuggen. Zum anderen können Sie in Stored Procedures,
Funktionen und Triggern Haltepunkte setzen, die dazu führen, dass der Debugger automatisch
anhält, wenn diese über ein Programm ausgeführt werden, das Sie in Visual Studio .NET
entwickeln und testen.
!
,
$- $
*
$
3 5
E
Visual Studio .NET-Professional kann lediglich die Personal-Edition des SQL Servers
debuggen. Visual Studio .NET-Enterprise ist in der Lage, mit der Standard- und die EnterpriseEdition zu arbeiten. Scheinbar ist es mit der Enterprise-Edition nicht möglich, die SQL-ServerPersonal-Edition zu debuggen. Wenigstens konnte ich mein Visual Studio .NET-EnterpriseEdition nicht dazu bewegen ...
$
,
Der direkte Aufruf ist sehr einfach. Suchen Sie die Stored Procedure dazu im Server-Explorer
und wählen Sie im Kontextmenü des Eintrags den Befehl IN GESPEICHERTE PROZEDUR
SPRINGEN.
Falls der zu debuggende SQL Server nicht im Server-Explorer auftaucht können
Sie über den Ordner DATENVERBINDUNGEN auch eine separate Verbindung zu
einer SQL-Server-Datenbank aufbauen.
Sichten, Stored Procedures, Funktionen und Trigger 99
Abbildung 44: Der Server-Explorer von Visual Studio .NET
Im zunächst erscheinenden Dialog können Sie die Parameterwerte eingeben.
Abbildung 45: Eingabe der Parameterwerte
Nachdem Sie Ihre Eingabe bestätigt haben wird die Prozedur ausgeführt und an der ersten
Anweisung angehalten.
Sichten, Stored Procedures, Funktionen und Trigger 100
Abbildung 46: Der Debugger hat die Prozedur angehalten
Ähnlich dem TSQL-Debugger können Sie nun mit F11 (Einzelschritt) und F10 (Prozedurschritt)
schrittweise weitergehen. In den unteren Fenstern sehen Sie die lokalen Variablen. Zusätzlich
können Sie über das ÜBERWACHEN-Register eigene Überwachungsausdrücke eingeben. Sehr
interessant ist auch das Befehlsfenster, in dem Sie gültige TSQL-Ausdrücke eingeben und über
Return ausführen können. Sie erhalten dann das Ergebnis des Ausdrucks und können so auch
(neue) Varianten von Ausdrücken ausprobieren, die in dieser Form nicht in der Prozedur
vorkommen. Betätigen Sie nun F11 um in die Funktion zu springen und diese zu debuggen.
.
#
Wie der TSQL-Debugger erlaubt auch der Visual Studio .NET-Debugger das Setzen von
Haltepunkten. Betätigen Sie auf einer Anweisung F9 um einen solchen zu setzen. Wenn Sie das
Programm mit F5 weiter ausführen, hält der Debugger am gesetzten Haltepunkt an.
Wie beim TSQL-Debugger sollten Sie das Programm vor dem Schließen des
Debuggers immer mit F5 zu Ende ausführen um das System nicht in einen
inkonsistenten Zustand zu versetzen.
B
5$%
7
*
$
In einigen Fällen reicht der direkte Aufruf einer Stored Procedure nicht aus um diese oder
untergeordnet aufgerufene Funktionen oder Trigger zu debuggen. Dies ist z. B. dann der Fall,
wenn ein TSQL-Programm eigentlich korrekt läuft, bei der Verwendung in einem mit Visual
Sichten, Stored Procedures, Funktionen und Trigger 101
Studio geschriebenen Programmen aber fehlerhaft ausgeführt wird, weil ungültige oder
unerwartete Parameter übergeben werden.
Um in diesem Kontext zu debuggen, können Sie im TSQL-Programm einfach einen Haltepunkt
setzen und das Visual Studio-Projekt ausführen. Wird im Programm eine Anweisung
ausgeführt, die zur indirekten Ausführung des TSQL-Programms führt, hält der Debugger
dieses am Haltepunkt an.
Das folgende Beispiel implementiert eine einfache C#-Konsolenanwendung, die unsere
Beispiel-Stored-Procedure ausführt:
using System;
using System.Data;
using System.Data.SqlClient;
namespace SP_Test
{
class Start
{
[STAThread]
static void Main(string[] args)
{
/* Verbindung zur Northwind-Datenbank auf dem lokalen
* SQL Server aufbauen */
SqlConnection con = new SqlConnection(
"Server=(local);Database=Northwind;Trusted_Connection=Yes");
con.Open();
/* SqlCommand-Objekt zur Ausführung der
* Stored Procedure erzeugen */
SqlCommand cmd = new SqlCommand("Update_PrimeNumber_Product_Price",
con);
/* Typ des Befehls definieren */
cmd.CommandType = CommandType.StoredProcedure;
/* Parameter definieren */
cmd.Parameters.Add("@CategoryId", SqlDbType.Int);
cmd.Parameters.Add("@Factor", SqlDbType.Real);
/* Parameterwerte übergeben */
cmd.Parameters["@CategoryId"].Value = 2;
cmd.Parameters["@Factor"].Value = 1.1;
try
{
/* Stored Procedure aufrufen */
cmd.ExecuteNonQuery();
/* Erfolg melden */
Console.WriteLine("Prozedur erfolgreich ausgeführt");
}
catch (Exception ex)
{
/* Fehler melden */
Console.WriteLine("Fehler bei der Ausführung der Prozedur: "
+ ex.Message);
}
/* Verbindung wieder schließen */
con.Close();
}
}
}
Um die indirekt aufgerufene TSQL-Funktion (oder die Stored Procedure) beim Aufruf durch
das Programm zu debuggen, öffnen Sie diese über den Befehl SKALAR WERTENDE FUNKTION
BEARBEITEN im Kontextmenü des Eintrags der Funktion im Server-Explorer und setzen in
Sichten, Stored Procedures, Funktionen und Trigger 102
dieser Funktion über F9 einen Haltepunkt. Führen Sie das C#-Programm dann über F5 aus,
sollte der Debugger am Haltepunkt anhalten.
Obwohl dies so in Newsgroups beschrieben wird, konnte ich mein Visual Studio.
NET-Enterprise-Edition nicht dazu bewegen, an einem Haltepunkt in einer Stored
Procedure oder Funktion anzuhalten. Möglicherweise lag das daran, dass ich die
Personal-Edition des SQL Servers einsetzte.
Sichten, Stored Procedures, Funktionen und Trigger 103
D
D
!
5
$- $
0 =F
5
#
,
#
0 =F
E
Wenn Sie die Größe des Transaktionsprotokolls fest einstellen wollen (oder aus
Performancegründen müssen), sollten Sie der Empfehlung von Microsoft folgen und von 25%
der Datenbankgröße als gutem Ausgangspunkt ausgehen. In der Praxis kann jedoch auch ein
wesentlich größeres Transaktionsprotokoll erforderlich sein. Dummerweise kann kein Benutzer
mehr mit der Datenbank arbeiten, wenn das Transaktionsprotokoll voll ist. Also: besser zu groß
als zu klein. Der Windows-Performance-Monitor hilft Ihnen bei der Entscheidung, wie groß das
Transaktionsprotokoll sein sollte, wenn Sie für dieses eine feste Größe eingestellt haben. In der
Praxis wird es wahrscheinlich meist sinnvoller sein, die Größe des Transaktionsprotokolls nicht
fest einzustellen, sondern dieses sich automatisch vergrößern zu lassen.
Das Transaktionsprotokoll (bzw. der gefüllte Bereichs eines fest eingestellten Protokolls) wird
mit der Zeit immer größer, wenn Sie die Datenbank gar nicht sichern oder lediglich Backups der
Datenbank (nicht des Transaktionsprotokolls) ausführen. Dabei kann es in der Praxis
vorkommen, dass die Datenbank vielleicht um die 50 MB Größe, das Transaktionsprotokoll
aber mehr als 1 GB Größe besitzt. Irgendwann sprengt die Größe des Transaktionsprotokolls
dann den freien Speicherplatz auf der Festplatte und die Datenbank wird in einen
fehlerverdächtigen Zustand geschaltet (und funktioniert natürlich nicht mehr).
Leider füllt sich das Transaktionsprotokoll unter bestimmten Umständen oft auch ohne
erkenntlichen Grund. In meinen ersten Versuchen mit dem SQL Server mit einer
Bestelldatenbank mit mehreren Hunderttausend Bestellungen war das Transaktionsprotokoll
zeitweise (nach mehreren Massenkopier- und Updateaktionen ohne das mir damals noch nicht
bekannte Massenprotokollierte Wiederherstellungsmodell) mit mehr als 250 MB gefüllt, obwohl
die Datenbank nur etwa 60 MB groß war. Microsoft beschreibt im MSDN die Gründe für das
Auffüllen des Transaktionsprotokolls, die sehr komplex sein können.
Einer der Hauptgründe für das Auffüllen des Transaktionsprotokolls ist, dass bei einem vollen
oder differentiellen Backup der Datenbank das Transaktionsprotokoll nicht geleert wird. Damit
wird Ihnen ermöglicht, dass Sie an Hand der im Transaktionsprotokoll aufgezeichneten
Aktionen einen Zustand wiederherstellen können, der vor dem letzten Backup der Datenbank
lag. Auch wenn Sie die Datenbank jeden Tag vollständig sichern, bleiben also alle
Transaktionen im Transaktionsprotokoll erhalten. Wenigstens so lange, bis Sie dieses sichern.
Erst das Backup des Transaktionsprotokolls nämlich entfernt die aufgezeichneten Transaktionen
aus diesem. Ein Backup des Transaktionsprotokolls bewirkt, dass alle abgeschlossenen
Transaktionen, die zum Zeitpunkt des Backups bereits in die Datenbank geschrieben wurden, im
Transaktionsprotokoll abgeschnitten werden. Das Transaktionsprotokoll wird dadurch also
verkleinert. Für den täglichen Normalbetrieb ist also ein regelmäßiges Backup des
Transaktionsprotokolls die beste Voraussetzung dafür, dass dieses nicht zu groß wird.
Dies führt bei einem automatisch vergrößerten Transaktionsprotokoll aber nicht dazu, dass die
Datei auch gleich verkleinert wird. Der SQL Server belässt die Datei bei ihrer Größe und
reserviert damit Speicherplatz für zukünftige Transaktionen. Wenn Sie allerdings die Datenbank
und das Transaktionsprotokoll regelmäßig sichern (wie ich es im folgenden Abschnitt
beschreibe), wird das Transaktionsprotokoll unter normalen Umständen nicht allzu groß
werden.
Manchmal treten leider aber auch nicht normale Umstände auf. Das ist z. B. dann der Fall, wenn
eine grone Anzahl von Daten angefügt, gelöscht oder geändert werden (ohne dazu die BuklCopy-Funktion zu nutzen, die das Transaktionsprotokoll umgeht). In diesem Fall kann das
Transaktionsprotokoll sehr groß werden und den Betrieb des SQL Servers gefährden. Dann
Administrieren des SQL Servers 104
sollten Sie selbst Hand anlegen (oder dies über einen Auftrag im SQL Server Agent, der weiter
unten beschrieben wird, automatisch ausführen lassen wenn das Transaktionsprotokoll häufiger
zu groß wird).
Beachtung verdient in diesem Zusammenhang auch das einfache Wiederherstellungs-Modell,
das Sie für eine Datenbank einstellen können. Mit diesem Modell wird das
Transaktionsprotokoll immer dann abgeschnitten, wenn ein Prüfpunkt auftritt, was (je nach
Einstellung) so etwa jede Minute der Fall ist. Bei einem Prüfpunkt schreibt der SQL Server alle
geänderten Datenseiten, die noch nicht physikalisch geschrieben wurden, in die Datenbank.
Man könnte der Meinung sein, diese Option wäre eine gute Alternative zu einem regelmäßigen
Backup des Transaktionsprotokolls, um dieses in der Größe zu beschränken. Da der SQL Server
in bestimmten Situationen nach einem Systemausfall zur Wiederherstellung der Datenbank
jedoch auch Information über abgeschlossene, bereits geschriebene Transaktionen benötigt und
Microsoft selbst diese Option nur für Testzwecke während der Entwicklung einer Datenbank
beschreibt, sollten sie besser das vollständige Wiederherstellungsmodell verwenden und ein
regelmäßiges Backup der Datenbank und des Transaktionsprotokolls ausführen.
>#
*
Als Vorbereitung der Verkleinerung des Transaktionsprotokolls sollten Sie die
Datenbankintegrität überprüfen und (automatisch) reparieren, was in SQL (am Beispiel einer
Warenwirtschafts-Datenbank) mit der folgenden Anweisung ausgeführt wird:
DBCC CHECKDB ('Warenwirtschaft')
Damit werden u. a. alle unbenötigten, aber reservierten Speicherseiten und Zeilen im Index
freigegeben.
Dann sollten Sie die Datenbank sichern, was in SQL in einer einfachen Form (wieder am
Beispiel einer Warenwirtschafts-Datenbank) folgendermaßen ausgeführt wird:
BACKUP DATABASE Warenwirtschaft
TO DISK='C:\Backups\Warenwirtschaft-Sicherung'
Nun können Sie das Transaktionsprotokoll mit der folgenden Anweisung in eine Datei sichern:
BACKUP LOG Warenwirtschaft TO DISK='C:\Backups\Warenwirtschaft-Log-Sicherung'
Alternativ können Sie auf die Sicherung verzichten und die abgeschlossenen Transaktionen
einfach abschneiden:
BACKUP LOG Warenwirtschaft WITH TRUNCATE_ONLY
Danach
sollten
Sie
nach
einer
Microsoft-Empfehlung
(support.microsoft.com/?id=272318) die Datenbank (noch einmal) komplett
sichern. Ob dies notwendig ist, bezweifle ich, da Sie diese ja bereits vor dem Abschneiden der
abgeschlossenen Transaktionen gesichert haben.
Das endgültige Verkleinern übernimmt dann die folgende Anweisung, der Sie den logischen
Dateinamen des Transaktionsprotokolls übergeben:
DBCC SHRINKFILE (Warenwirtschaft_Log)
Administrieren des SQL Servers 105
D"
, #
+
Microsoft empfiehlt, eine Unternehmensdatenbank einmal wöchentlich und deren
Transaktionsprotokoll täglich zu sichern. Die so erzeugte Backups sollten auf einem
Sicherungsmedium (z. B. einem Dat-Streamer) gesichert werden. Alle TransaktionsprotokollBackups sollten über zwei Wochen aufgehoben werden; alle Datenbank-Backups über zwei
Monate.
Abweichend von diesem Schema sollte die Datenbank in den folgenden Fällen gesichert
werden:
•
direkt nach der Erzeugung.
•
nach jeder unprotokollierten Operation (z. B. Massenkopieren mit der Option ‚select
into/bulk copy‘).
•
nach der Erzeugung von neuen Datenbankobjekten (Tabellen, Views, Indizes etc.).
Die master-Datenbank sollte nach jeder Änderung der Struktur einer Datenbank und nach jeden
Hinzufügen bzw. Entfernen von Datenbanken ebenfalls gesichert werden.
Die msdb-Datenbank sollte nach jeder Änderung der Aufgaben des SQL Server Agent gesichert
werden.
Verwechseln Sie Backup und Restore nicht mit dem automatischen Wiederherstellen
(Recovering) von Datenbanken nach einem Serverausfall. Nach einem Serverausfall stellt der
SQL Server die Datenbanken mit Hilfe des Transaktionsprotokoll automatisch wieder her ohne
ein Backup zu verwenden.
Das Backup der Datenbanken ist wichtig für den Fall, dass
•
das System aufgrund eines Stromausfalls ausfällt und Dateien beschädigt werden,
•
eine Festplatte ausfällt,
•
das Betriebssystem ausfällt,
•
eine Anwendung fehlerhaft arbeitet und die Datenbank beschädigt (z. B. Datensätze löscht),
•
ein Benutzer fehlerhafte Eingaben macht oder aus Versehen Datensätze löscht.
Theoretisch müsste es ausreichen, die Datenbank- und TransaktionsprotokollDateien über eine externe Backup-Software regelmäßig zu sichern und im
Fehlerfall diese Dateien vom Sicherungsmedium zurückzuholen. In der Praxis ist
dieses Vorgehen jedoch nicht praktikabel, da die vom SQL Server verwendeten
Dateien nur dann überschrieben werden können, wenn diese nicht in Benutzung
sind, d.h., wenn der SQL Server nicht läuft. Ein Backup und Restore über den SQL
Server kann jedoch ausgeführt werden, auch wenn der SQL Server zurzeit in
Benutzung ist.
Diese Aufgaben können Sie von Hand vornehmen. Für den täglichen Betrieb sollten Sie diese
Aufgaben jedoch dem Agenten überlassen, der weiter unten beschrieben wird.
Administrieren des SQL Servers 106
D"
!
Der SQL Server 2000 unterstützt drei Wiederherstellungs-Modelle, die ich im Abschnitt 5.1
bereits beschrieben habe. Sie müssen eines dieser Modelle in den Datenbankoptionen einstellen,
damit Sie eine zu Ihrer Datenbank passende Backupstrategie umsetzen können.
,
!
Im einfachen Modell wird das Transaktionsprotokoll bei einem Prüfpunkt einfach
abgeschnitten. Dabei wird der Speicherplatz der Transaktionen, die bereits in die Datenbank
geschrieben wurden, freigegeben. Da das Transaktionsprotokoll beim einfachen Modell nur die
aktiven Transaktionen beinhaltet, bringt das Backup dieses Protokolls nichts und wird deswegen
auch nicht ermöglicht. Sie können im einfachen Modell lediglich ein Backup und Restore der
Datenbankdateien (vollständig und differentiell) ausführen, nicht des Transaktionsprotokolls.
Tritt ein Fehler nach einem Backup auf, sind alle Änderungen zwischen dem Backup und dem
Fehlerzeitpunkt verloren. Das einfache Modell bringt den »Vorteil« mit, dass das
Transaktionsprotokoll nicht sehr groß werden kann. Der Nachteil ist, dass Sie erweiterte
Backup-Strategien, die das Transaktionsprotokoll mit einbeziehen, nicht anwenden können.
4
!
Das
vollständige
Wiederherstellungs-Modell
belässt
alle
Transaktionen
im
Transaktionsprotokoll bis dieses oder die Datenbank gesichert wird (erst dann werden die
inaktiven Transaktionen abgeschnitten). Es ermöglicht damit ein Sichern der Datenbank
(vollständig und differentiell) und ein separates Sichern des Transaktionsprotokolls. Dieses für
die meisten größeren Datenbanken sinnvolle Modell erlaubt z. B. das Sichern der gesamten
Datenbank jeden Tag um 00:00 und das Sichern des (kleineren und damit schneller gesicherten)
Transaktionsprotokolls jede Stunde. Damit ist die Wahrscheinlichkeit sehr gering, dass bei
einem Crash des Servers viele Änderungen verloren gehen.
#
!
Dieses dem vollständigen Modell ähnliche Modell führt dazu, dass bestimmte
Massenänderungen an den Daten (z. B. über SELECT INTO) nur minimal protokolliert werden.
Damit werden diese Massenoperationen zwar performanter ausgeführt und benötigen weniger
Speicherplatz im Transaktionsprotokoll. Beim einem Crash ist die Gefahr des Datenverlustes
bezogen auf die in den Massenoperationen veränderten Daten aber sehr groß.
Administrieren des SQL Servers 107
D""
, #$
Die richtige Backup-Strategie zu finden ist eine in der Praxis nicht einfache Aufgabe. Prinzipiell
können Sie eine Datenbank nach den folgenden Schemen sichern:
Einfaches Wiederherstellungsmodell:
•
Sichern der gesamten Datenbank in regelmäßigen Abschnitten;
•
Sichern der gesamten Datenbank in regelmäßigen Abschnitten; Sichern der Änderungen seit
dem letzten Backup in kürzeren regelmäßigen Abschnitten (differentielles Backup).
Vollständiges Wiederherstellungs-Modell:
•
Sichern der gesamten Datenbank in regelmäßigen Abschnitten;
•
Sichern der gesamten Datenbank in regelmäßigen Abschnitten; Sichern der Änderungen seit
dem letzten Backup in kürzeren regelmäßigen Abschnitten.
•
Sichern der gesamten Datenbank in regelmäßigen Abschnitten;
Transaktionsprotokolls in kürzeren regelmäßigen Abschnitten;
•
Sichern der gesamten Datenbank in regelmäßigen Abschnitten; Sichern der Änderungen seit
dem letzten Backup in kürzeren regelmäßigen Abschnitten; Sichern des
Transaktionsprotokolls in noch kürzeren regelmäßigen Abschnitten.
Sichern
des
Dabei müssen Sie beachten, dass das Sichern der gesamten Datenbank sehr viel (Prozessor)Zeit und Ressourcen in Anspruch nimmt. Ein differentielles Sichern nimmt weniger
(Prozessor-)Zeit und Ressourcen in Anspruch, das Sichern des Transaktionsprotokolls am
wenigsten. Eine Datenbank, die recht intensiv genutzt wird, sollten Sie während der
Nutzungszeit nicht vollständig und idealerweise auch nicht differentiell sichern. Idealerweise
sichern Sie die Datenbank einmal täglich zu einem Zeitpunkt, an dem nur wenige oder keine
Benutzer mit der Datenbank arbeiten. Dann sollten Sie zu gegebenen Zeitpunkten mit wenig
Belastung (z. B. in den Betriebspausen) das Transaktionsprotokoll sichern. Das Ganze können
Sie übrigens über den SQL Server Agent automatisieren, wie ich im Abschnitt 9.3 kurz
beschreibe.
Ein differentielles Backup ist bei dieser Strategie in meinen Augen nicht sinnvoll,
es sei denn, Sie verwenden aus irgendwelchen Gründen das einfache
Wiederherstellungsmodell.
Administrieren des SQL Servers 108
D"/
, #
.
Das Backup einer Datenbank starten Sie von Hand über das Kontextmenü der Datenbank (ALLE
TASKS / DATENBANK SICHERN).
Abbildung 47: Der Dialog zum Backup einer Datenbank
Die Option TRANSAKTIONSPROTOKOLL steht nur zur Verfügung wenn die
Datenbank das vollständige Wiederherstellungsmodell verwendet und wenn Sie
bereits zuvor ein Backup der Datenbankdatei(en) vorgenommen haben.
Sie können die Datenbank vollständig oder differentiell sichern. Das vollständige Sichern
speichert alle abgeschlossenen Transaktionen der gesamten Datenbank. Ein darauf folgendes
differentielles Backup sichert lediglich die Änderungen seit dem letzten Vollbackup.
Im Feld NAME können Sie einen Namen für die Sicherung eingeben, unter dem Sie alle Teile
des Backups sichern können (Datenbankdateien, Transaktionsprotokolle). Unter diesem Namen
können Sie ein Backup später vollständig wiederherstellen.
Wählen Sie als Ziel FESTPLATTE aus, wenn Sie nicht auf Band sichern wollen. Fügen Sie dann
über den HINZUFÜGEN-Schalter einzelne Dateien (in der Regel nur eine Datei) hinzu, in die das
Backup geschrieben werden soll. Oben können Sie einstellen, ob sie die Datenbank komplett
oder nur die Änderungen seit dem letzten Backup oder nur das Transaktionsprotokoll sichern
wollen.
Administrieren des SQL Servers 109
Bei der Vergabe des Dateinamens empfiehlt sich, das aktuelle Datum und eine
Information mit in den Namen aufzunehmen, dass es sich dabei um ein Backup der
Datenbankdatei (und nicht ges Transaktionsprotokolls) handelt. Nennen Sie die
Datei z. B. Fahrradverleih_15.01.2003_Daten.
Normalerweise (und genau das macht der SQL Server mit seinen Wartungsplänen auch) sollten
Sie ein komplettes Backup der Datenbank in eine einzige Datei schreiben.
Unten können Sie einstellen, ob das Backup an eine bereits vorhandene Datei gleichen Namens
nur angehangen wird, oder ob diese Datei mit dem Backup überschrieben wird. Wenn Sie wie
der SQL-Server-Wartungsplan vorgehen, erzeugen Sie pro Backup eine Datei, in deren Namen
das Datum vorkommt und deren Name deswegen eindeutig ist.
Wenn Sie die Option TERMINPLAN einschalten und einen Zeitplan eingeben,
bedeutet das übrigens, dass dieses Backup als Job für den SQL Server Agent
eingetragen wird.
, #
5
#
Schließen Sie das Backup der Datenbank nun ab. Ändern Sie danach einige Daten in der
Datenbank, sodass der SQL Server das Transaktionsprotokoll wieder mit Transaktionen füllt.
Wenn Sie dann den Backup-Dialog öffnen, können Sie auch das Transaktionsprotokoll sichern.
Abbildung 48: Backup des Transaktionsprotokolls
Administrieren des SQL Servers 110
Beachten Sie, dass Sie vor dem Backup den noch vom vorherigen Backup stehen
gebliebenen Datei-Eintrag entfernen und einen neuen für das Transaktionsprotokoll
einfügen.
D"8
+
Wiederherstellen können Sie eine Datenbank ähnlich dem Backup über das Kontextmenü der
Datenbank. Der Enterprise Manager zeigt im Restore-Dialog alle aktuellen Backups an.
Abbildung 49: Dialog zum Restore einer Datenbank
Der Restore-Dialog listet die bisherigen Backups einer Datenbank auf, wenn Sie diese in der
Liste SICHERUNGSKOPIEN DER FOLGENDEN DATENBANK ANZEIGEN auswählen.
Tragen Sie den korrekten Namen der Datenbank in die obere Liste ein. Sie können eine
Datenbank auch unter einem anderen Namen restaurieren, um z. B. Daten, die aus Versehen
gelöscht wurden, in die originale Datenbank zurück zu kopieren. Für alle Backups können Sie in
der Liste wählen, welche wiederhergestellt werden sollen. Die Reihenfolge wird vom SQL
Server automatisch korrekt eingestellt. Sie sollten dabei aber darauf achten, dass Sie nicht ein
Backup abwählen, das in der Mitte der zu restaurierenden Backups liegt, damit die Daten
korrekt restauriert werden.
Administrieren des SQL Servers 111
Dadurch dass Sie einige der letzten Transaktionsprotokoll-Sicherungen bzw.
differentielle Datenbank-Sicherungen abwählen können, können Sie ein Backup
auch nur bis zu einem bestimmten Zeitpunkt wiederherstellen. Diese Möglichkeit
ist immer dann wichtig wenn ein Anwender aus »Versehen« Daten gelöscht oder
fehlerhaft geändert hat. In diesem Fall können Sie die Datenbank in eine neue
Datenbank (mit einem anderen Namen) zurücksichern und die geänderten Daten
dann »von Hand« (über SQL) aus der wiederhergestellten in die aktuelle
Datenbank zurückschreiben. Wenn Sie dazu SQL verwenden, geben Sie einfach
den Datenbank- und den Besitzernamen vor den Tabellennamen an.
Beispiel: Wiederherstellen der versehentlich gelöschten Produkte der Kategorie 1 aus einem in
eine separate Datenbank restaurierten Backup:
INSERT INTO Fahrradverleih.dbo.Products
SELECT * FROM Fahrradverleih_Backup.dbo.Products WHERE CategoryId = 1
+
$6
,
3
Schreiben Sie ein Backup in einer neuen oder anderen Installation des SQL Servers zurück,
tauchen in der Liste der Backups der Datenbank natürlich keine passenden Einträge auf. In
diesem Fall wählen Sie in die Wiederherstellen-Option VON MEDIEN und wählen Sie die Datei
oder das Band aus, in der das Backup erfolgte.
Abbildung 50: Restore einer Datenbank direkt aus einer Datei
Wenn Sie eine Datenbank auf ein anderes System restaurieren (was ein ideales Vorgehen ist,
um eine Datenbank von einem auf ein anderes System zu übertragen), müssen Sie u. U. den
Speicherort der Datenbank anpassen. Der SQL Server verwendet ansonsten den originalen
Administrieren des SQL Servers 112
Speicherort, der u. U. auf dem Zielsystem nicht vorhanden ist. Tragen Sie die gewünschten
Dateinamen im Register OPTIONEN ein.
Abbildung 51: Optionen -Register des Restore-Dialogs
Wenn Sie eine vorhandene Datenbank mit dem Backup überschreiben wollen, müssen Sie in
diesem Register die Option WIEDERHERSTELLUNG ÜBER VORHANDENE DATENBANK
ERZWINGEN einstellen.
D/
$- $
Der SQL Server Agent ermöglicht das automatische Ausführen bestimmter Aufgaben, wie z. B.
dem Backup oder der Reorganisation einer Datenbank in bestimmten frei wählbaren
Zeitabschnitten. So können Sie z. B. verschiedene Aufgaben wöchentlich (am Sonntag z. B.)
ausführen und andere täglich (z. B. ab 0:00 Uhr).
Außerdem kann der SQL Server Agent Systemressourcen überwachen und beim Über- bzw.
Unterschreiten von festgelegten Werten Aktionen ausführen, wie zum Beispiel das Senden einer
E-Mail.
Jobs und Alarme können Sie von Hand über den SQL SERVER AGENT-Ordner im
VERWALTUNG-Ordner des Enterprise Managers anlegen, was hier jedoch nicht beschrieben
wird. Die häufigsten Jobs, wie das Backup einer Datenbank oder das regelmäßige
Reorganisieren einer Datenbank, können sie wesentlich einfacher über einen Wartungsplan
(Maintenance Plan) einrichten. Die Einrichtung dieser Pläne erreichen sie über das
Kontextmenü der Datenbank (ALLE TASKS / WARTUNGSPLAN). Der Dialog zur Erstellung eines
Wartungsplans führt Sie in mehreren Schritten durch die Erstellung von Jobs, mit denen Sie die
Datenbank reorganisieren und sichern können. Ein Wartungsplan erzeugt die notwendigen Jobs
für den SQL Server nahezu automatisch.
Administrieren des SQL Servers 113
G 5##
5 ,
G
)
$#
6
4
Der Wert einer Identity-Spalte wird ja, wie Sie bereits wissen, bei jedem neuen Datensatz vom
SQL Server automatisch erhöht. Wenn Sie jedoch einen Datensatz einfügen wollen, und den
Wert der Identity-Spalte selbst vergeben wollen (z. B. weil Sie den Datensatz an der Position
eines zuvor gelöschten Datensatzes einfügen wollen), funktioniert dies zunächst einmal nicht.
Sie können das automatische Einfügen der Identity-Spalte für eine Tabelle pro Benutzer jedoch
auch abschalten und den Identity-Wert dann selbst definieren. Dazu müssen Sie den Datensatz
mit TSQL-Anweisungen einfügen:
/* Identity-Insert für Kunden-Tabelle ermöglichen */
SET IDENTITY_INSERT dbo.Kunden ON
/* Datensatz mit eigenem Identity-Wert anfügen */
INSERT INTO Kunden (Kunden_Nr, Firmenname, Straße, Plz, Ort)
VALUES (1001, 'Panzerknacker AG', 'Tresorweg 42', '12345', 'Entenhausen')
/* Identity-Insert für Kunden-Tabelle wieder ausschalten */
SET IDENTITY_INSERT dbo.Kunden OFF
Sie müssen dabei eine Feldliste angeben (INSERT INTO Kunden VALUES (...) funktioniert so
nicht). Wenn Sie einen Datensatz hinten anfügen, verwendet der SQL Server beim nächsten
neuen Datensatz den um 1 erhöhten Wert für die Identity-Spalte.
Der Identity-Wert existierender Datensätze lässt sich leider nicht verändern. Wenn Sie einen
solchen Datensatz neu definieren wollen, müssen Sie den Datensatz löschen und wie oben
beschrieben wieder einfügen.
G"
5
# 4
5
Temporär erzeugte Tabellen eignen sich für viele Aufgaben, bei denen normale Abfragen
versagen. Oft ist es einfacher, eine Tabelle temporär zu erzeugen, weiter zu bearbeiten und den
Inhalt auszugeben, als dazu teilweise kompliziert geschachtelte Abfragen zu verwenden.
# 4
5
Temporäre Tabellen erzeugen Sie wie normale Tabellen. Dem Tabellennamen stellen Sie
allerdings ein oder zwei # voraus:
CREATE TABLE #MyTempTable (Year int NOT NULL, Amount real NOT NULL)
Ein # bewirkt, dass die Tabelle nur für die aktuelle Sitzung gültig ist. Andere Sitzungen können
nicht auf diese Tabelle zugreifen und zudem gleichzeitig gleichnamige Tabellen erzeugen.
Wenn Sie zwei # angeben, ist die Tabelle für alle Sitzungen global.
=,
# 4
5
In einer Stored Procedure erzeugte temporäre Tabellen werden automatisch gelöscht, wenn die
Stored Procedure beendet ist. Alle anderen lokalen Tabellen werden gelöscht, wenn die Sitzung
beendet ist. Globale temporäre Tabellen werden automatisch erst dann gelöscht wenn der Server
heruntergefahren wird (da beim Hochfahren die Datenbank tempdb, in der diese Tabellen
gespeichert werden, neu erzeugt wird).
Sie können eine temporäre Tabelle natürlich auch explizit löschen:
DROP TABLE #MyTempTable
Tipps und Tricks 114
7
# 4
5
>
Normalerweise sollten Sie lokale temporäre Tabellen vor dem Erzeugen immer löschen (falls
diese bereits in der aktuellen Sitzung erzeugt wurden). Da dabei allerdings ein Fehler auftritt
wenn die Tabelle nicht existiert, sollten Sie zuvor abfragen, ob die Tabelle existiert. Dieses
Abfragen kann auch vor dem Erzeugen oder Verwenden einer globalen temporären Tabelle
sinnvoll sein. Zur Abfrage der Existenz einer lokalen temporären Tabelle verwenden Sie den
folgenden »Trick«:
DECLARE @TableName nvarchar(255)
SET @TableName = 'tempdb.[' + SESSION_USER + '].#<Tabellenname>'
if object_id(@TableName) is not null
begin
/* Tablle ist vorhanden und kann z. B. gelöscht werden */
DROP TABLE #<Tabellenname>
end
Bei der Abfrage der Objekt-Id der Tabelle müssen Sie den kompletten Tabellennamen angeben,
der aus dem Datenbanknamen, dem Namen des Benutzers und dem eigentlichen Tabellennamen
besteht. Damit Sie den aktuellen Benutzer korrekt mit in den Namen einbinden, ermitteln Sie
dessen Namen über die Variable SESSION_USER. Da der Name auch Sonderzeichen beinhalten
kann, sollten Sie diesen wie im Beispiel in eckige Klammern einfügen. Mit dem so
zusammengesetzten Tabellennamen können Sie die Existenz der Tabelle ermitteln.
Tipps und Tricks 115
,
Bowman, Judith S., Emerson, Sandra L., Darnovsky Marcy: The practical SQL Handbook.
Using Structured Query Language. Addison-Wesley Developers Press. 1997.
Date, Chris J, Darwen Hugh: SQL-Der Standard. SQL/92 mit den Erweiterungen CLI und PSM.
Addison Wesley München. 1999.Anmerkung: Standardwerk, aber kompliziert geschrieben und
der Autor verweist sehr häufig für Erklärungen auf andere Kapitel.
Soukup, Ron, Delaney, Kalen: Inside Microsoft SQL Server 7.0. Microsoft Press Redmond,
Washington. 1999.
Delaney, Kalen: Inside Microsoft SQL Server 2000. Microsoft Press Redmond, Washington.
2001.
Anhang 116
" )
>
ALTER-Anweisung 73, 86, 87, 94
Datenbankoptionen 31
Anweisungsrechte 62
Datenbank-Rollen 58
AppleTalk ADSP 15
Datenintegrität 17
Arbeitsspeicher 5
Datenseiten 22
Backup 106
Datentypen 38
Banyan VINES 15
bigint 38
BEGIN TRANSACTION 22
binary 39
Benutzerdefinierte Datentypen 18
bit 40
Benutzernamen 57
char 38
Benutzerverwaltung 57
cursor 40
Beziehungen 49
datetime 38
bigint-Datentyp 38
decimal 39
binary-Datentyp 39
float 39
bit-Datentyp 40
image 39
char-Datentyp 38
int 38
Check Constraints 45
money 39
Check-Einschränkungen 45
nchar 38
über SQL anlegen 54
ntext 39
Check-Option 72
numeric 39
Checkpoints 23
nvarchar 38
Client/Server-Konzept 17
real 39
Clustered Index 45
smalldatetime 38
COMMIT TRANSACTION 22
smallint 38
Constraints 18
smallmoney 39
Cursor 84
sql_variant 40
cursor-Datentyp 40
sysname 40
Database Owner 59, 68
table 40
Data-Mining 1
text 39
Data-Warehousing 2
timestamp 40
Dateigruppen 30
tinyint 38
Datenbankdiagramm 49
uniqueidentifier 40
Datenbanken
varbinary 39
auf mehrere Dateien aufteilen 30
varchar 38
Dateigruppen 30
datetime-Datentyp 38
Default-Dateigruppe 30
DB-Benutzer 57
erzeugen 28
dbo 59, 68
im Zugriff beschränken 32
Debuggen 94
Optionen 31
im TSQL-Debugger 96
Primäre Dateigruppe 30
in Visual Studio .NET 99
RAID-Systeme 30
decimal-Datentyp 39
Transaktionsprotokoll 30
deleted 89
Wiederherstellungs-Modell 32
DENY 64
Index 117
Developer Edition 3
inserted 89
Diagramme 49
Installation 5
Dienst Manager 24
int-Datentyp 38
Dienste 5
IPC-Mechanismus 14
Diensteprogramme 15
Konsistenz 17
DRI 49
Kontrollstrukturen 81
Editionen
Lazywriter-Thread 23
Developer 3
Log Sequenz Nummer 22
Enterprise 2
Login 57
MSDE 4
Login-Objekte 57
Personal 3
Logins
Standard 2
anlegen 64
Windows CE 3
modifizieren 64
Einschränkungen 18
über SQL ändern 55
LSN 22
Maintenance Plan 113
Enterprise Edition 2
Microsoft Distributed Transaction Coordinator 19
Enterprise Manager 25
money-Datentyp 39
Festplatten 5
MSDE 4
Festplattenspeicher 5
MSDTC 19
File-Server 17
MSSQLServer-Dienst 19
float-Datentyp 39
Multi-Protocol 14
Fremdschlüssel
Named Pipes 14
über SQL anlegen 55
nchar-Datentyp 38
Füllfaktor 44
Netzwerk-Bibliotheken 13
Funktionen 69, 86
NT-Authentifizierung 66
verändern 87
ntext-Datentyp 39
Gespeicherte Prozeduren 18, 73
numeric-Datentyp 39
Globale Variablen 80
nvarchar-Datentyp 38
GRANT 63
NWLink IPX/SPX 15
Gruppierte Indizes 45
Objektrechte 63
Guest 68
Objekt-Rechte 61
GUID-Werte 41
ODS 19
Haltepunkte
OLAP 1
im TSQL-Debugger 98
Open Data Service 19
im Visual Studio .NET-Debugger 101
Operatoren 83
Hardware 5
Pages 22
Identitätsspalte 41
Personal Edition 3
IF-Abfrage 81
Primärschlüssel 40
image-Datentyp 39
Indizes 41
über SQL anlegen 54
Prozessor 5
Füllfaktor 44
Public-Rolle 59
Gruppierte Indizes 45
RAID-Systeme 6, 30
über SQL ändern 56
real-Datentyp 39
über SQL anlegen 55
Rechte
Index 2
Datenbankspezifische Rechte 57
Parameter und Variablen 75
Systemweite Rechte 57
Rückgabetypen 75
Verwaltung 57
verändern 86
Recovering 23
sysname-Datentyp 40
Referentielle Integrität 49
Systemkatalog 23
mit DRI 49
Regeln 18
Tabellen
Erzeugen 37
Rekursive Trigger 33
Temporäre 114
Restore 106
über SQL anlegen 53
REVOKE 64
table-Datentyp 40
ROLLBACK TRANSACTION 22
TCP/IP 13
Rollen 57, 58
TCP/IP-Sockets 14
anlegen 60
RowGUID 41
Temporäre Tabellen 114
text-Datentyp 39
Rules 18
timestamp-Datentyp 40
sa 68
tinyint-Datentyp 38
Seiten 22
Transaction Logs 21
Server
Transaktionen 21
Registration im Enterprise Manager 25
Servername 5
Server-Rollen 58
Explizite 22
Implizite 21
Transaktionsprotokoll
Service Manager 24
Größe 104
Sichten 18, 69, 70
verkleinern 105
Check-Option 72
Transaktionsprotokolle 21
Erweiterte Sicherheit 72
Trigger 18, 69, 88
sortieren 71
verändern 73
deleted-Tabelle 89
inserted-Tabelle 89
smalldatetime-Datentyp 38
Rollback 93
smallint-Datentyp 38
testen 92
smallmoney-Datentyp 39
verändern 94
Sortierung
Default bei der Installation 13
SQL Server Agent 113
TSQL 81
Operatoren 83
TSQL-Debugger 96
SQL Server Dienste 5
Unique Constraint 43
SQL Server-Authentifizierung 57, 66
Unique Index 43
sql_variant-Datentyp 40
uniqueidentifier-Datentyp 40
SQLServerAgent-Dienst 19
varbinary-Datentyp 39
Standard Edition 2
varchar-Datentyp 38
Statistiken 33
Views 18, 69, 70
Stored Procedure 69
Visual Studio .NET
Stored Procedures 18, 73
zum Debuggen von TSQL 99
Aufruf in VBA 77
Wartungsplan 113
Globale Variablen 80
While-Schleife 81
Output-Parameter 77
Wiederherstellungs-Modelle 32, 107
Index 3
Windows CE Edition 3
Windows-Authentifizierung 57
Windows NT-Authentifizierung 66
Zerrissene Seiten 33
Index 4