vorheriges KapitelInhaltsverzeichnisIndexInfoseitenächstes Kapitel



19


Transact-SQL: Eine Einführung

Ziele

Ein Überblick über Transact-SQL

Erweiterungen zu ANSI-SQL

Datentypen

Auf die Datenbank mit Transact-SQL zugreifen

Flußsteuerung

Platzhalter-Operatoren von Transact-SQL

Berichte mit COMPUTE erstellen

Datumsformate

Diagnosewerkzeuge von SQL Server - SET-Befehle

Zusammenfassung

Fragen & Antworten

Workshop



Ziele

Das heutige Material rundet die vorherigen Darstellungen ab, da Transact-SQL eine Ergänzung zum akzeptierten SQL-Standard ist. Die heutige Lektion zeigt ...



Ein Überblick über Transact-SQL

Tag 14 ist kurz auf statisches SQL eingegangen. Die Beispiele in Lektion 14 haben die Verwendung von eingebettetem SQL in Sprachen der dritten Generation wie C herausgestellt. Bei dieser Programmiermethode ändert sich der eingebettete SQL-Code nicht und ist demnach recht eingeschränkt. Mit dynamischem SQL kann man dagegen die gleichen Funktionen in einer prozeduralen Programmiersprache realisieren und innerhalb des SQL-Codes variable Kriterien erlauben.


Wir haben mehrfach darauf hingewiesen, daß die meisten Datenbankhersteller die Standard-SQL-Sprache um zahlreiche Erweiterungen bereichern. Transact-SQL ist das Datenbankprodukt von Sybase und Microsoft SQL Server. Das Pendant von Oracle heißt PL/SQL. Diese Sprachen realisieren in vollem Umfang die bisher im Buch dargestellte Funktionalität. Darüber hinaus enthält jedes Produkt verschiedene Erweiterungen zum ANSI SQL-Standard.



Erweiterungen zu ANSI-SQL

In dieser Lektion demonstrieren wir SQL-Erweiterungen für das Erstellen von Programmen anhand der Sprache Transact-SQL von Sybase und Microsoft SQL Server. Zu dieser Sprache gehören sowohl Konstrukte, die man in Sprachen der dritten Generation findet, als auch einige SQL-Server-spezifische Funktionen, die sich als nützliche Werkzeuge für den Datenbankprogrammierer herausstellen.



Wer verwendet Transact-SQL?

Jeder, der dieses Buch liest, kann mit Transact-SQL arbeiten - sowohl Programmierer, die gelegentlich mit relationalen Datenbanken zu tun haben und hin und wieder Abfragen schreiben, als auch Entwickler, die Anwendungen schreiben und Objekte wie Trigger und gespeicherte Prozeduren erstellen.


Benutzer von Sybase und Microsoft SQL Server, die alle Möglichkeiten bei der Programmierung relationaler Datenbanken ausschöpfen wollen, kommen an den Funktionen von Transact-SQL nicht vorbei.


Die grundlegenden Komponenten von Transact-SQL

SQL-Erweiterungen überwinden als prozedurale Sprache die Beschränkungen von SQL. Beispielsweise lassen sich mit Transact-SQL die Transaktionen einer Datenbank unmittelbar steuern, und man kann prozedurale Datenbankprogramme schreiben, die den Programmierer von zeitaufwendigen Programmieraufgaben befreien.


Tag 19 behandelt die folgenden Schlüsselmerkmale von Transact-SQL:



Datentypen

Tag 9 ist unter anderem auf Datentypen eingegangen. Beim Erstellen von Tabellen in SQL muß man für jede Spalte einen bestimmten Datentyp angeben.


Datentypen sind in den jeweiligen Implementierungen von SQL unterschiedlich definiert, da jeder Datenbankserver die Daten auf andere Weise speichert. Beispielsweise existieren in Oracle andere Datentypen als in SQL Server von Sybase und Microsoft.

SQL Server von Sybase und Microsoft unterstützt die folgenden Datentypen.



Zeichenstrings


Numerische Datentypen


Datumswerte


Datentypen für Währungen

Währungstypen fügt man mit Hilfe eines vorangestellten Dollarzeichens ein. Dazu ein Beispiel:


insert payment_tbl (KUNDEN_NR, ZAHL_DATUM, ZAHL_BETRAG)
values (012845, '01.05.1997', $2099.99)



Binäre Strings


bit: ein logischer Datentyp

Die im Datentyp bit gespeicherten Werte können entweder 1 oder 0 sein. Man verwendet diesen Datentyp beispielsweise, um eine Spalte mit einem Kennzeichen - einem sogenannten Flag - zu versehen. Eine 1 kann dann bedeuten, daß eine Bedingung wahr (TRUE) ist, während 0 für eine falsche (FALSE) Bedingung steht. Das folgende Beispiel zeigt mit einer Spalte des Datentyps bit einen Testzustand an.


create table test_flag
( ind_id int not null,
test_ergebnis int not null,
ergebnis_flag bit not null)


Die Spalte ergebnis_flag ist als bit-Spalte definiert, in der ein bestandener Test mit dem Wert TRUE (oder 1) und ein nichtbestandener Test mit dem Wert FALSE (oder 0) gespeichert wird.

Achten Sie in den restlichen Beispielen dieses Tages auf die Datentypen, die in Tabellen und im Transact-SQL-Code zum Einsatz kommen.


Der Code in den heutigen Beispielen ist sowohl in Groß- als auch Kleinschreibung dargestellt. SQL-Schlüsselwörter sind zwar in den meisten Implementierungen von SQL nicht von der Groß-/Kleinschreibung abhängig, dennoch sollte man sich davon anhand der Dokumentation überzeugen.


Auf die Datenbank mit Transact-SQL zugreifen

Genug der Vorrede, kommen wir zu praktischen Beispielen. Bauen Sie zunächst die folgenden Tabellen in der Datenbank BASEBALL auf, damit Sie die Beispiele der heutigen Lektion nachvollziehen können.



Die Datenbank BASEBALL

Die Datenbank BASEBALL besteht aus drei Tabellen, in denen typische Angaben von Baseball-Spielen aufgezeichnet werden: die Tabelle BATTERS (Schlagmann), die Tabelle PITCHERS (Werfer) und die Tabelle TEAMS. Diese Datenbank begleitet uns durch alle weiteren Beispiele dieses Tages.



Die Tabelle BATTERS

NAME char(30)
TEAM int
AVERAGE float
HOMERUNS int
RBIS int


Die obige Tabelle kann man mit der folgenden Transact-SQL-Anweisung erstellen:


1> create database BASEBALL on default
2> go
1> use BASEBALL
2> go
1> create table BATTERS (
2> NAME char(30),
3> TEAM int,
4> AVERAGE float,
5> HOMERUNS int,
6> RBIS int)
7> go


Zeile 1 erstellt die Datenbank. Man gibt die Datenbank BASEBALL an und erzeugt dann darunter die Tabelle BATTERS.

Geben Sie die Daten aus Tabelle 19.1 in die Tabelle BATTERS ein.


Der Befehl go, der jede Transact-SQL-Anweisung im obigen Beispiel trennt, gehört nicht zur Sprache Transact-SQL. Der Zweck von go ist die Übergabe jeder Anweisung von einer Frontend-Anwendung an SQL Server.

Tabelle 19.1: Daten für die Tabelle BATTERS

Name

Team

Average

Homeruns

RBIs

Billy Brewster

1

.275

14

46

John Jackson

1

.293

2

29

Phil Hartman

1

.221

13

21

Jim Gehardy

2

.316

29

84

Tom Trawick

2

.258

3

51

Eric Redstone

2

.305

0

28


Die Tabelle PITCHERS

Die Tabelle PITCHERS läßt sich mit der folgenden Transact-SQL-Anweisung erstellen:


1> use BASEBALL
2> go
1> create table PITCHERS (
2> NAME char(30),
3> TEAM int,
4> WON int,
5> LOST int,
6> ERA float)
7> go


Geben Sie die Daten aus Tabelle 19.2 in die Tabelle PITCHERS ein.


Tabelle 19.2: Daten für die Tabelle PITCHERS

Name

Team

Won

Lost

Era

Tom Madden

1

7

5

3.46

Bill Witter

1

8

2

2.75

Jeff Knox

2

2

8

4.82

Hank Arnold

2

13

1

1.93

Tim Smythe

3

4

2

2.76


Die Tabelle TEAMS

Die Tabelle TEAMS läßt sich mit der folgenden Transact-SQL-Anweisung erstellen:


1> use BASEBALL
2> go
1> create table TEAMS (
2> TEAM_ID int,
3> CITY char(30),
4> NAME char(30),
5> WON int,
6> LOST int,
7> TOTAL_HOME_ATTENDANCE int,
8> AVG_HOME_ATTENDANCE int)
9> go


Geben Sie die Daten aus Tabelle 19.3 in die Tabelle TEAMS ein.


Tabelle 19.3: Daten für die Tabelle TEAMS

Team_ID

City

Name

Won

Lost

Total_Home_-Attendance

Avg_Home_-Attendance

1

Portland

Beavers

72

63

1,226,843

19,473

2

Washington

Representatives

50

85

941,228

14,048

3

Tampa

Sharks

99

36

2,028,652

30,278


Lokale Variablen deklarieren

Jede Programmiersprache bietet irgendeine Methode für die Deklaration von lokalen (oder globalen) Variablen, in denen man Daten speichern kann. Transact-SQL bildet hier keine Ausnahme. Die Deklaration einer Variablen in Transact-SQL ist eine recht einfache Prozedur. Man verwendet folgende Syntax mit dem Schlüsselwort DECLARE:


Eine Zeichenstringvariable zur Speicherung von Spielernamen deklariert man mit der folgenden Anweisung:


1> declare @name char(30)
2> go


Beachten Sie das Symbol @ vor dem Namen der Variablen. Dieses Symbol ist erforderlich und wird vom Abfrageprozessor zur Identifikation von Variablen verwendet.



Globale Variablen deklarieren

Wenn Sie sich weiter in die Dokumentation von Transact-SQL vertiefen, stoßen Sie auf das Symbol @@. SQL Server kennzeichnet damit globale Systemvariablen.


Die Deklaration eigener globaler Variablen ist vor allem nützlich, wenn man mit gespeicherten Prozeduren arbeitet. SQL Server verwaltet auch mehrere globale Systemvariablen, auf die der Benutzer des Datenbanksystems zurückgreifen kann. Tabelle 19.4 zeigt eine Liste dieser Variablen.


Tabelle 19.4: Globale Variablen von SQL Server

Variablenname

Zweck

@@char_convert

0 bei aktiver Zeichensatzumwandlung

@@client_csid

Zeichensatz-ID des Clients

@@client_csname

Zeichensatzname des Clients

@@connections

Anzahl der Anmeldungen seit Start von SQL Server

@@cpu_busy

In Ticks gemessene Zeitspanne, die die CPU seit Start von SQL Server beschäftigt ist

@@error

Enthält den Fehlerstatus

@@identity

Letzter in eine Identitätsspalte eingefügter Wert

@@idle

In Ticks gemessene Zeitspanne, die SQL Server seit Start im Leerlauf ist

@@io_busy

In Ticks gemessene Zeitspanne, die SQL Server mit Ein-/Ausgaben verbracht hat

@@isolation

Momentane Isolationsebene des Transact-SQL-Programms

@@langid

Definiert ID der lokalen Sprache

@@language

Definiert den Namen der lokalen Sprache

@@maxcharlen

Maximale Länge eines Zeichens

@@max_connections

Maximale Anzahl von Verbindungen, die mit SQL Server hergestellt werden können

@@ncharsize

Durchschnittliche Länge eines nationalen Zeichens

@@nestlevel

Verschachtelungsebene der aktuellen Programmausführung

@@pack_received

Anzahl der Eingabepakete, die durch SQL Server seit dem Start eingelesen wurden

@@pack_sent

Anzahl der Ausgabepakete, die durch SQL Server seit dem Start gesendet wurden

@@packet_errors

Anzahl der Fehler, die seit Start von SQL Server aufgetreten sind

@@procid

ID der momentan ausgeführten gespeicherten Prozedur

@@rowcount

Anzahl der vom letzten Befehl beeinflußten Zeilen

@@servername

Name des lokalen SQL Servers

@@spid

ID des aktuellen Prozesses

@@sqlstatus

Enthält Statusinformationen

@@textsize

Maximale Länge von Text- oder Bilddaten, die mit der SELECT-Anweisung zurückgegeben werden

@@thresh_hysteresis

Änderung im freien Speicher, der für die Aktivierung einer Schwelle erforderlich ist

@@timeticks

Anzahl der Mikrosekunden pro Tick

@@total_errors

Anzahl der Fehler, die beim Lesen oder Schreiben aufgetreten sind

@@total_read

Anzahl der Lesezugriffe auf den Datenträger seit Start von SQL Server

@@total_write

Anzahl der Schreibzugriffe auf den Datenträger seit Start von SQL Server

@@tranchained

Momentaner Transaktionsmodus des Transact-SQL-Programms

@@trancount

Verschachtelungsebene der Transaktionen

@@transtate

Momentaner Status einer Transaktion nach Ausführung einer Anweisung

@@version

Datum der aktuellen Version von SQL Server.


Variablen verwenden

Mit dem Schlüsselwort DECLARE kann man mehrere Variablen in einer einzigen Anweisung deklarieren (obwohl das Ganze leicht unübersichtlich werden kann, vor allem, wenn man sich den Code später ansieht). Ein Beispiel für diese Art der Anweisung:


1> declare @batter_name char(30), @team int, @average float
2> go


Der nächste Abschnitt erläutert, wie man diese Variablen in Programmoperationen einsetzt.



Daten in Variablen speichern

Variablen sind nur innerhalb des aktuellen Anweisungsblocks verfügbar. In der Sprache Transact-SQL führt man einen Anweisungsblock mit dem Befehl go aus. (In Oracle dient das Semikolon demselben Zweck.) Der Gültigkeitsbereich einer Variablen bezieht sich auf die Verwendung der Variablen innerhalb der aktuellen Transact-SQL-Anweisung.


Variablen lassen sich nicht einfach mit Hilfe des Gleichheitszeichens initialisieren. Probieren Sie die folgende Anweisung aus, und beachten Sie den zurückgegebenen Fehler.


1> declare @name char(30)
2> @name = 'Billy Brewster'
3> go


Sie sollten eine Fehlermeldung erhalten haben, die eine ungeeignete Syntax in Zeile 2 bemängelt. Eine Variable ist nämlich mit einem SELECT-Befehl zu initialisieren. (Jawohl, derselbe Befehl, den Sie bereits beherrschen.) Wiederholen Sie das obige Beispiel mit der korrekten Syntax:


1> declare @name char(30)
2> select @name = 'Billy Brewster'
3> go


Diese Anweisung wird ohne Beanstandung ausgeführt. Hätten Sie weitere Anweisungen vor Ausführung von go eingefügt, könnten Sie hier die Variable @name verwenden.



Daten in lokale Variablen abrufen

Variablen speichern oft Daten, die aus einer Datenbank abgerufen wurden. Man kann diese Variablen dann in gebräuchlichen SQL-Befehlen wie SELECT, INSERT, UPDATE und DELETE verwenden. Beispiel 19.1 zeigt die Verwendung von Variablen in dieser Weise.


Beispiel 19.1

Dieses Beispiel ruft den Namen des Spielers in der Datenbank BASEBALL ab, der den höchsten Schlagdurchschnitt aufweist und für die Portland Beavers spielt.


1> declare @team_id int, @player_name char(30), @max_avg float
2> select @team_id = TEAM_ID from TEAMS where CITY = 'Portland'
3> select @max_avg = max(AVERAGE) from BATTERS where TEAM = @team_id
4> select @player_name = NAME from BATTERS where AVERAGE = @max_avg
5> go


Dieses Beispiel gliedert sich in drei Abfragen, um die Verwendung von Variablen zu demonstrieren.


Der Befehl PRINT

Ein weiteres nützliches Feature von Transact-SQL ist der Befehl PRINT, mit dem man die Ausgabe auf das Anzeigegerät schreiben kann. Der Befehl hat die folgende Syntax:


Obwohl PRINT nur Zeichenstrings anzeigt, bietet Transact-SQL eine Anzahl von Funktionen, die verschiedene Datentypen in Strings (und umgekehrt) umwandeln können.


Beispiel 19.2

Dieses Beispiel wiederholt Beispiel 19.1, gibt aber am Ende den Namen des Spielers aus.


1> declare @team_id int, @player_name char(30), @max_avg float
2> select @team_id = TEAM_ID from TEAMS where CITY = 'Portland'
3> select @max_avg = max(AVERAGE) from BATTERS where TEAM = @team_id
4> select @player_name = NAME from BATTERS where AVERAGE = @max_avg
5> print @player_name
6> go


Beachten Sie, daß man eine Variable in der WHERE-Klausel (oder irgendeiner anderen Klausel) wie einen konstanten Wert verwenden kann.



Flußsteuerung

Wahrscheinlich die leistungsfähigste Gruppe von Transact-SQL-Funktionen betrifft die Steuerung des Programmablaufs. Wenn Sie bereits mit anderen bekannten Sprachen wie C, Cobol, Pascal oder Visual Basic programmiert haben, sind Sie sicherlich schon mit Befehlen wie IF...THEN und Schleifenanweisungen vertraut. Dieser Abschnitt beschreibt die wichtigsten Befehle zur Steuerung des Programmablaufs.



Die Anweisungen BEGIN und END

Transact-SQL kennzeichnet mit den Anweisungen BEGIN und END die Anfangs- und Endpunkte von Codeblöcken. (Andere Sprachen verwenden für diesen Zweck unter anderem geschweifte Klammern oder andere Operatoren.) Häufig findet man die BEGIN/END-Anweisungen in Verbindung mit IF...ELSE-Anweisungen und WHILE-Schleifen. Das folgende Beispiel zeigt einen einfachen Block mit BEGIN und END:



Die Anweisung IF...ELSE

Eine der grundlegendsten Programmkonstruktionen ist die Anweisung IF...ELSE. Nahezu jede Programmiersprache unterstützt diese Konstruktion. Beispielsweise lassen sich damit die aus einer Datenbank abgerufenen Werte testen. Die Transact-SQL-Syntax für die IF...ELSE-Anweisung sieht folgendermaßen aus:


Für jeden Zweig der Bedingungskonstruktion existiert ein eigener BEGIN/END-Block mit entsprechenden Anweisungen. Es gehört zum guten Programmierstil, die Anweisungsblöcke um eine bestimmte Anzahl von Leerzeichen einzurücken und diese Konvention in der gesamten Anwendung beizubehalten. Dadurch verbessert sich die Lesbarkeit des Programms, und man verringert die Anzahl der Fehler, die sich allein aufgrund einer unübersichtlichen Darstellung einschleichen.


Beispiel 19.3

Dieses Beispiel erweitert Beispiel 19.2 durch eine Prüfung auf den Schlagdurchschnitt eines Spielers. Wenn der Durchschnitt des Spielers über .300 liegt, soll er eine Gehaltserhöhung erhalten. Andernfalls könnte der Spieler schnell im Abseits verschwinden!


Beispiel 19.3 setzt die IF...ELSE-Anweisung ein, um Bedingungen innerhalb der Anweisung auszuwerten. Wenn die erste Bedingung gleich TRUE ist, erscheint der angegebene Text auf dem Bildschirm. Der alternative Text wird bei jeder anderen Bedingung (ELSE) ausgegeben.


1> declare @team_id int, @player_name char(30), @max_avg float
2> select @team_id = TEAM_ID from TEAMS where CITY = 'Portland'
3> select @max_avg = max(AVERAGE) from BATTERS where TEAM = @team_id
4> select @player_name = NAME from BATTERS where AVERAGE = @max_avg
5> if (@max_avg > .300)
6> begin
7> print @player_name
8> print 'Bekommt eine Gehaltserhöhung!'
9> end
10> else
11> begin
12> print @player_name
13> print 'Komm'' wieder, wenn du besser triffst!'
14> end
15> go


Beispiel 19.4

Mit dieser neuen IF-Anweisung lassen sich die einfachen BASEBALL-Datenbankabfragen etwas interessanter gestalten. Beispiel 19.4 fügt einen IF...ELSE IF...ELSE-Zweig in den Code von Beispiel 19.3 ein.


1> declare @team_id int, @player_name char(30), @max_avg float
2> select @team_id = TEAM_ID from TEAMS where CITY = 'Portland'
3> select @max_avg = max(AVERAGE) from BATTERS where TEAM = @team_id
4> select @player_name = NAME from BATTERS where AVERAGE = @max_avg
5> if (@max_avg > .300)
6> begin
7> print @player_name
8> print 'Bekommt eine Gehaltserhöhung!'
9> end
10> else if (@max_avg > .275)
11> begin
12> print @player_name
13> print 'Nicht schlecht. Hier ist eine Anerkennung!'
14> end
15> else
16> begin
17> print @player_name
18> print 'Komm'' wieder, wenn du besser triffst!'
19> end
20> go


In Transact-SQL lassen sich auch Bedingungsfunktionen in einer IF-Anweisung einsetzen. Entsprechende Funktionen können auf bestimmte Bedingungen oder Werte testen. Wenn die Funktion TRUE zurückgibt, wird der IF-Zweig abgearbeitet. Andernfalls durchläuft das Programm den ELSE-Zweig (falls dieser vorhanden ist), wie es das vorhergehende Beispiel gezeigt hat.



Die Bedingung EXISTS

Mit dem Schlüsselwort EXISTS läßt sich prüfen, ob eine SELECT-Anweisung einen Wert zurückgegeben hat. In diesem Fall durchläuft das Programm den IF-Zweig. Beispiel 19.5 demonstriert diese Logik.


Beispiel 19.5

In diesem Beispiel wertet das Schlüsselwort EXISTS eine Bedingung in IF aus. Die Bedingung ist in Form einer SELECT-Anweisung formuliert.


1> if exists (select * from TEAMS where TEAM_ID > 5)
2> begin
3> print 'Es existiert!!'
4> end
5> else
6> begin
7> print 'Nichts zu finden!'
8> end



Das Ergebnis einer Abfrage testen

Mit der IF-Anweisung läßt sich auch das Ergebnis testen, das eine SELECT-Abfrage zurückgibt. Beispiel 19.6 implementiert diese Möglichkeit, um auf den maximalen Schlagdurchschnitt unter den Spielern zu prüfen.


Beispiel 19.6

Dieses Beispiel ist ähnlich zu Beispiel 19.5. Es verwendet die SELECT-Anweisung, um eine Bedingung zu testen. Dieses Mal testen wir aber die Bedingung mit dem Zeichen größer als (>).


1> if (select max(AVG) from BATTERS) > .400
2> begin
3> print 'UNGLAUBLICH!!'
4> end
5> else
6> print 'TED WILLIAMS IST ABGESCHLAGEN!'
7> end


Informieren Sie sich über die IF-Anweisung in Ihrer konkreten SQL-Implementierung. Denken Sie sich verschiedene Bedingungen aus, die Sie in der Datenbank BASEBALL (oder irgendeiner anderen) überprüfen möchten. Starten Sie einige Abfragen, um sich mit dem Einsatz der IF-Anweisung vertraut zu machen.



Die WHILE-Schleife

Mit der WHILE-Schleife unterstützt Transact-SQL eine weitere bekannte Programmkonstruktion. Die Syntax lautet:


Beispiel 19.7

Die WHILE-Schleife arbeitet die enthaltenen Anweisungen wiederholt ab, bis der logische Ausdruck FALSE liefert. Das nächste Beispiel inkrementiert eine lokale Variable (namens COUNT) in einer einfachen WHILE-Schleife.


1> declare @COUNT int
2> select @COUNT = 1
3> while (@COUNT < 10)
4> begin
5> select @COUNT = @COUNT + 1
6> print 'Erneuter Schleifendurchlauf!'
7> end
8> print 'Schleife beendet!'


Beispiel 19.7 implementiert eine einfache FOR-Schleife. Andere Implementierungen von SQL, wie etwa PL/SQL von Oracle, stellen tatsächlich eine FOR-Konstruktion bereit. Sehen Sie bitte in Ihrer Dokumentation nach, ob Ihr System diesen Befehl unterstützt.


Der Befehl BREAK

Mit dem Befehl BREAK läßt sich der sofortige Austritt aus einer WHILE-Schleife erzwingen. Den Befehl BREAK setzt man häufig in Verbindung mit einem IF-Test ein, um bei einem bestimmten Ergebnis einer Bedingung die WHILE-Schleife zu verlassen. Damit setzt die Programmausführung mit den Befehlen fort, die unmittelbar auf die END-Anweisung folgen. Beispiel 19.8 zeigt den Einsatz des BREAK-Befehls. Hier wird auf eine willkürlich gewählte Zahl (sagen wir @COUNT = 8) geprüft. Wenn die Bedingung erfüllt ist, verläßt das Programm die WHILE-Schleife.


Beispiel 19.8

Beachten Sie die Anordnung des BREAK-Befehls nach der Auswertung der ersten Bedingung in IF.


1> declare @COUNT int
2> select @COUNT = 1
3> while (@COUNT < 10)
4> begin
5> select @COUNT = @COUNT + 1
6> if (@COUNT = 8)
7> begin
8> break
9> end
10> else
11> begin
12> print 'Erneuter Schleifendurchlauf!'
13> end
14> end
15> print 'Schleife beendet!'


Der BREAK-Befehl bewirkt das Verlassen der Schleife, wenn die Variable @COUNT den Wert 8 erreicht.


Der Befehl CONTINUE

Der Befehl CONTINUE ist ein weiterer Spezialbefehl, der sich innerhalb einer WHILE-Schleife einsetzen läßt. Dieser Befehl bewirkt, daß die Schleifenausführung sofort an den Beginn der Schleife springt, statt den Rest der Schleife abzuarbeiten und dann erst wieder an den Beginn zurückzugehen. Wie beim BREAK-Befehl verwendet man den Befehl CONTINUE häufig in einer IF-Anweisung, um auf eine Bedingung zu testen und dann eine Aktion auszulösen. Beispiel 19.9 zeigt einen Einsatzfall.


Beispiel 19.9

Beachten Sie die Anordnung der CONTINUE-Anweisung nach der Auswertung der ersten Bedingung in IF.


1> declare @COUNT int
2> select @COUNT = 1
3> while (@COUNT < 10)
4> begin
5> select @COUNT = @COUNT + 1
6> if (@COUNT = 8)
7> begin
8> continue
9> end
10> else
11> begin
12> print 'Erneuter Schleifendurchlauf!'
13> end
14> end
15> print 'Schleife beendet!'


Beispiel 19.9 ist Beispiel 19.8 ähnlich, arbeitet aber mit dem CONTINUE-Befehl statt mit BREAK. Bei @COUNT = 8 verläßt das Programm nunmehr nicht die Schleife, sondern geht an den Anfang der WHILE-Schleife zurück und arbeitet die Anweisungen in der Schleife weiter ab.


Mit der WHILE-Schleife durch eine Tabelle scrollen

SQL Server und viele andere Datenbanksysteme verfügen über den speziellen Objekttyp Cursor, mit dem man datensatzweise durch die Datensätze einer Tabelle scrollen kann. (Siehe dazu Tag 13.) Allerdings unterstützen manche Datenbanksysteme keine scrollbaren Cursor. Beispiel 19.10 zeigt einen Ansatz, wie man mit einer WHILE-Schleife arbeitet, um etwa die Funktionalität eines Cursors zu implementieren, wenn diese Funktionalität nicht automatisch zur Verfügung steht.


Beispiel 19.10

Mit der WHILE-Schleife kann man durch Tabellen datensatzweise blättern. Transact-SQL verwaltet die Variable rowcount, mit der man SQL Server anweisen kann, nur eine Zeile bei einer Abfrage zurückzugeben. Wenn man mit einem anderen Datenbankprodukt arbeitet, sollte man sich über ähnliche Einstellungen informieren. Durch Setzen von rowcount auf 1 (der Standardwert 0 bedeutet unbegrenzt) gibt SQL Server nur einen Datensatz bei einer SELECT-Abfrage zurück. Mit diesem einen Datensatz können Sie dann alle gewünschten Operationen anstellen. Indem Sie den Inhalt einer Tabelle in eine temporäre Tabelle selektieren, die am Ende der Operation gelöscht wird, können Sie eine Zeile pro Abfrage auswählen und diese Zeile nach getaner Arbeit löschen. Wenn alle Zeilen aus der Tabelle ausgewählt würden, müßte man jede Zeile in der Tabelle durcharbeiten! (Wie gesagt, diese Funktionalität entspricht nur in etwa der eines Cursors.) Führen wir nun das Beispiel aus.


1> set rowcount 1
2> declare @PLAYER char(30)
3> create table temp_BATTERS (
4> NAME char(30),
5> TEAM int,
6> AVERAGE float,
7> HOMERUNS int,
8> RBIS int)
9> insert temp_BATTERS
10> select * from BATTERS
11> while exists (select * from temp_BATTERS)
12> begin
13> select @PLAYER = NAME from temp_BATTERS
14> print @PLAYER
15> delete from temp_BATTERS where NAME = @PLAYER
16> end
17> print 'Schleife beendet!'


Beachten Sie, daß sich über die Variable rowcount lediglich die Anzahl der aus einer SELECT-Operation zurückgegebenen Zeilen festlegen läßt. Sollte die WHERE-Klausel eines DELETE-Befehls fünf Zeilen zurückgeben, würden auch fünf Zeilen gelöscht! Weiterhin ist anzumerken, daß man die Variable rowcount wiederholt zurücksetzen kann. Demzufolge läßt sich innerhalb der Schleife die Datenbank nach bestimmten Zusatzinformationen abfragen, indem man einfach rowcount auf 1 setzt, bevor man den Schleifendurchlauf fortsetzt.


Platzhalter-Operatoren von Transact-SQL

Der Einsatz von Platzhalterbedingungen (Wildcards) in SQL wurde in Lektion 3 eingeführt. Der Operator LIKE erlaubt die Verwendung von Platzhalterbedingungen in SQL-Anweisungen. Transact-SQL erweitert die Flexibilität von Platzhalterbedingungen. Die folgende Übersicht faßt die Wildcard-Operationen von Transact-SQL zusammen.



Berichte mit COMPUTE erstellen

In Transact-SQL lassen sich auch zusammengefaßte Datenbankberichte erstellen. Die Syntax des Befehls COMPUTE ist eng mit dem Pendant in SQL*Plus verwandt. (Siehe dazu Tag 20.)


Die folgende Abfrage liefert einen Bericht, der alle Schläger, die Anzahl der Heimspiele jedes Schlagmanns und die Gesamtzahl der Heimspiele aller Schlagmänner zeigt:


select name, homeruns
from batters
compute sum(homeruns)


Im obigen Beispiel führt COMPUTE allein Berechnungen auf dem Bericht als Ganzes aus, während COMPUTE BY die Berechnungen auf angegebenen Gruppen und dem gesamten Bericht ausführt, wie es das folgende Beispiel zeigt:

Für FUNCTION können die Aggregatfunktionen SUM, MAX, MIN etc. stehen. Ausdruck ist gewöhnlich ein Spaltenname oder ein Alias.



Datumsformate

Sybase und Microsoft SQL Server kann Datumswerte in eine Tabelle in verschiedenen Formaten einfügen. Außerdem lassen sich Datumswerte in verschiedenen Formaten abrufen. Dieser Abschnitt zeigt, wie man mit dem Befehl CONVERT von SQL Server das Anzeigeformat eines Datums beeinflussen kann.


Die folgenden Datumsformate sind in SQL Server verfügbar, wenn man mit der Funktion CONVERT arbeitet:


Tabelle 19.5: Datumsformate in SQL Server

Formatcode

Darstellung

100

mon dd yyyy hh:miAM (oder PM)

101

mm/dd/yy

102

yy.mm.dd

103

dd/mm/yy

104

dd.mm.yy

105

dd-mm-yy

106

dd mon yy

107

mon dd, yy

108

hh:mi:ss

109

mon dd, yyyy hh:mi:ss:mmmAM (oder PM)

110

mm-dd-yy

111

yy/mm/dd

112

yymmdd

113

dd mon yyyy hh:mm:ss:mmm (24h)

114

hh:mi:ss:mmm (24h)

select 'ZAHL_DATUM' = convert(char(15), ZAHL_DATUM, 104)
from RECHNUNGEN
where KUNDEN_NR = 012845


ZAHL_DATUM
---------------
01.05.1997


Das obige Beispiel verwendet den Formatcode 104 in der CONVERT-Funktion. Entsprechend der Tabelle der Datumsformate zeigt Code 104 das Datum im deutschen Format dd.mm.yy an.


Diagnosewerkzeuge von SQL Server - SET-Befehle

In Transact-SQL lassen sich mit SET-Befehlen verschiedene Optionen aktivieren, um Transact-SQL-Anweisungen zu analysieren. Einige der gebräuchlichsten SET-Befehle zeigt die folgende Übersicht:


Mit den folgenden Befehlen kann man steuern, was als Teil der Ausgabe von Abfragen anzuzeigen ist:


Die Optimierung von SQL-Anweisungen ist Thema von Tag 15.


Zusammenfassung

Tag 19 führt eine Reihe von Themen ein, die etwas Biß in Ihre SQL-Programmierpraxis bringen. Die bisher in diesem Buch behandelten SQL-Themen sind äußerst wichtig und liefern die Grundlage für Ihre gesamte Datenbankprogrammierung. Allerdings bilden diese Themen erst den Anfang. Die gestern und heute erläuterten prozeduralen Sprachkonzepte von SQL bauen auf Ihren SQL-Grundkenntnissen auf. Es handelt sich um leistungsfähige Konstruktionen, mit denen Sie auf die Daten in Ihrer relationalen Datenbank zugreifen können.


Die Sprache Transact-SQL gehört zu den Produkten SQL Server von Sybase und Microsoft und stellt viele Programmkonstrukte bereit, die man in bekannten Sprachen der dritten und vierten Generation findet. Dazu gehört die IF-Anweisung, die WHILE-Schleife und die Möglichkeit, lokale und globale Variablen zu deklarieren.


Denken Sie daran, daß Tag 19 nur eine kurze Einführung in die Funktionen und Verfahren des Transact-SQL-Codes bietet. Vertiefen Sie sich ruhig in Ihre Dokumentation und probieren Sie alle Werkzeuge aus, die Ihnen zur Verfügung stehen. Eine detaillierte Behandlung von Transact-SQL finden Sie in den entsprechenden Dokumentationen zu Microsoft SQL Server.



Fragen & Antworten

Frage:

Stellt SQL eine FOR-Schleife bereit?

Antwort:

Programmierkonstrukte wie FOR-Schleifen, WHILE-Schleifen und CASE-Anweisungen sind Erweiterungen zu ANSI-SQL. Demzufolge variiert die Verwendung dieser Elemente von einem Datenbanksystem zum anderen. Beispielsweise bietet Oracle die FOR-Schleife, während Transact-SQL (SQL Server) diese Konstruktion nicht kennt. Man kann natürlich in einer WHILE-Schleife eine Variable inkrementieren und auf diese Weise die FOR-Schleife nachbilden.

Frage:

Ich entwickle eine Windows- (oder Macintosh-) Anwendung, in der die Benutzeroberfläche aus Elementen wie Fenstern und Dialogfeldern besteht. Kann ich mit der PRINT-Anweisung Meldungen an den Benutzer ausgeben?

Antwort:

SQL ist vollständig plattformunabhängig. Demzufolge öffnet die PRINT-Anweisung kein eigenes Meldungsfenster. Um Meldungen an den Benutzer auszugeben, können Ihre SQL-Prozeduren vordefinierte Werte zurückgeben, die Erfolg oder Scheitern anzeigen. Dann kann der Benutzer vom Status der Abfragen unterrichtet werden. (Der PRINT-Befehl ist vor allem bei der Fehlersuche hilfreich, da eine innerhalb einer gespeicherten Prozedur ausgeführte PRINT-Anweisung überhaupt nicht auf dem Bildschirm ausgegeben wird.)


Workshop


Kontrollfragen

1. Richtig oder falsch: Die Bezeichnung SQL in PL/SQL von Oracle und Transact-SQL von Microsoft/Sybase impliziert, daß diese Produkte vollständig kompatibel zum ANSI-Standard sind.


2. Richtig oder falsch: Statisches SQL ist nicht so flexibel wie dynamisches SQL, obwohl die Leistungsbilanz von statischem SQL besser sein kann.



Übungen

1. Wenn Sie nicht mit SQL Server von Microsoft/Sybase arbeiten, sollten Sie die Erweiterungen Ihres Produkts zu ANSI-SQL mit den heute erwähnten Erweiterungen vergleichen.


2. Schreiben Sie eine Anweisungsgruppe, die das Vorhandensein einer bestimmten Bedingung überprüft. Wenn diese Bedingung TRUE ist, führen Sie eine bestimmte Operation aus. Andernfalls führen Sie eine andere Operation aus.



Ein Imprint des Markt&Technik Buch- und Software-Verlag GmbH.
Elektronische Fassung des Titels: SQL in 21 Tagen, ISBN: 3-8272-2020-3


vorheriges KapitelTop Of PageInhaltsverzeichnisIndexInfoseitenächstes Kapitel