einfache SQL-Einführung für GTDS-Anwender

[Anfang] [nächster Abschnitt]

[Teil I]

Wichtigste SQL-Statements, Syntax und Beispiele unter ORACLE(TM)

Konventionen
Namenskonventionen
Eingeben von SQL-Statements unter Oracle allgemein
Syntax und Aufbau von SQL-Statements
Create-Statements
SELECT-Statement
INSERT-Statement
UPDATE-Statement
DELETE-Statement
Transaktionsbearbeitung
Zugriffsrechte bei mehreren Benutzern einer SQL-Datenbank
Einige Sätze zum Datenaustausch unter Oracle

Konventionen

Ausdruck bedeutet
GROSSBUCHSTABEN Schlüsselwort, muß genau so geschrieben werden, wie es dasteht, nur GROSS- oder klein-schreibung ist egal. Beispiel :
CREATE select
<name> Ist Platzhalter für einen Eigennamen (Tabelle, Spalte, ... ) oder einen Ausdruck (z.B. die WHERE -Bedingung). Im echten Statement tritt an seine Stelle z.B. der Tabellenname (vgl. Beispiele) oder die WHERE-Bedingung. Die Winkelzeichen <> dürfen selbstverständlich nicht mit eingegeben werden.
[FETTDRUCK] [<name>] bezeichnet optionale Teile eines Statements. Diese Teile kann man also verwenden, kann sie aber auch weglassen. Dabei kann es sich um Schlüsselworte, aber auch um Platzhalter für Namen, z.B. von Tabellen oder Spalten handeln Die Klammern [] dürfen selbstverständlich nicht mit eingegeben werden.
EINS|ANDERES Der senkrechte Strich | trennt Alternativen. In diesem Beispiel müßte EINS oder ANDERES angegeben werden. (Aber nicht der Strich | !)
<spaltenname,...> Ein Komma , mit nachfolgenden Punkten ... deutet an, daß der betreffende Teil mehrfach wiederholt werden kann (aber nicht muß). Typisches Beispiel wären die Tabellen- und Spaltenlisten im SELECT -Statement.

Namenskonventionen


In der folgenden Beschreibung kommen häufig Namen vor, die anstelle von Platzhaltern einzusetzen sind, z.B. Tabellennamen, Spaltennamen, Indexnamen, usw.. Für diese Namen gelten im SQL- Umfeld folgende Regeln ( nicht überall genau gleich ) :


Eingeben von SQL-Statements unter Oracle allgemein

SQL-Statements können Sie unter Oracle über die Tools sqlplus oder sqldba bzw. svrmgrl eingeben. Zu Ihrem Produktset gehört in der Regel das mächtigere sqlplus ([Bedienung]).

Benutzer-freundlichere Wege zu den Daten gibt es, sowohl von Oracle (z.B. Data Browser ) als auch aus anderen, z.T. mehr oder weniger freien Quellen. SQLPLUS ist jedoch weitverbreitet und nahezu überall vorhanden, wo es Oracle gibt.

In einer Unix(®)-Umgebung, wie sie bei vielen GTDS-Registern noch existiert, sind einige Besonderheiten zu beachten. Vorraussetzung für den Aufruf von sqlplus oder sqldba sind einige korrekte zu setzende Umgebungsvariable (Fehler an dieser Stelle sind nicht immer gleich offensichtlich: beim Aufruf von SQL*Plus könnten solche Meldungen wie sqlplus: not found. oder Error during Connect o.a. erscheinen). Im Zweifelfalle sollten Sie zuerst . oraenv (Bourne oder Korn-Shell) bzw. source coraenv (C-Shell) aufrufen. Näheres hierzu s. Systemverwalter-Hinweise. Die Datenbank, auf die Sie zugreifen, wird beim Aufruf beider Tools implizit durch die Umgebungsvariablen ORACLE_SID (muß gesetzt sein) und evtl. TWO_TASK bestimmt. Da auf Ihren Rechnern i.d.R. nur eine Datenbank laufen wird, können hier keine Probleme beim Aufruf auftreten. In vernetzten Umgebungen mit mehreren erreichbaren Oracle-Datenbanken gibt es erweiterte Aufrufmöglichkeiten, um die Zieldatenbank zu bestimmen.



Syntax und Aufbau von SQL-Statements


Format von SQL-Statements


SQL ist eine Format-freie Sprache, d.h. wie die Statements optisch aussehen ist prinzipiell völlig gleich. Wie Sätze in einer normalen Sprache bestehen SQL-Statements aus einzelnen Worten, die durch Zwischenraum (sog. white space, d.h. Leer-, Tabulatorzeichen und Zeilentrenner) voneinander getrennt werden.

Beispiel:


SELECT * FROM STAMM ;

oder

select    *               from
stamm ;

oder

Select
*
FROM
stamm ;
führt immer zum gleichen Resultat !

Semikolon ; am Schluß :

SQL-Statements unter Oracle werden mit einem Semikolon oder einem Schrägstrich (Slash) einzeln auf einer Zeile abgeschlossen.

Beispiele:


select * from PATIENT ;

oder

select * from PATIENT
/

Kommentare :

In SQL können an fast jeder Stelle Kommentare stehen, sie müssen unter Oracle in /* */ (wie in C) eingeschlossen werden.

Beispiel :


select * from STAMM /* holt alle Datensätze der Tabelle stamm */ ;

Daneben sind auch Kommentare im Ansi-Stil möglich. Sie erstecken sich von einem -- (zwei Bindestriche) bis zum Ende der Zeile. Wichtige Ausnahme : In den Queries in der Reportdefinition für SQL*ReportWriter dürfen gar keine Kommentare stehen, sonst treten evtl. rätselhafte Fehler auf !

Hinweis : Die Beispiele im Folgenden beziehen sich auf die Datenbank des Tumordokumentationssystems GTDS, sowie zwei Beispieltabellen.


Create-Statements


Datenbank erstellen

Unter Oracle ist der Vorgang der Datenbankgenerierung recht umfangreich, es sei denn man bedient sich vorgefertigter Skripte und Prozeduren. Hinweise hierzu gibt folgende Literatur:

- Oracle Database Administrator's Guide
- Oracle Installation and User's Guide (IUG) für Ihr System
- Systemverwalter-Hinweise für das GTDS

Inzwischen stehen auf PC-Plattformen wohl auch grafische Werkzeuge für diese Aufgabe zur verfügung.

Unter Oracle bedeutet Datenbank nahezu immer eine umfangreiche Sammlung von vielen Tabellen, die einen gemeinsamem Namen für die Datenbank (Database Instance Name oder System Identifier, ORACLE_SID) teilen und in wenigen Dateien des Betriebsystems gespeichert sind.

Die Tabellen innerhalb einer Datenbank können verschiedenen logischen Benutzern gehören. Für eine sichere Trennung wird gesorgt.

Diese Terminologie unterscheidet sich deutlich von der typischer PC-Datenbanksysteme, wo oft zahlreiche kleine "Datenbänklein" mit einer oder zwei Tabellen existieren.


Neue Tabelle erstellen :

Dafür ist CREATE TABLE zuständig. Die prinzipielle Syntax zum Erzeugen einer Tabelle sieht folgendermaßen aus :


CREATE TABLE <Tabellenname>  (
    <Spaltenname>  <Datentyp> [ NOT NULL ] ,
    .....,
    <Spaltenname>  <Datentyp>
) ;
Für <Datentyp> ist einzusetzen :
CHAR(n) für Zeichenketten (also z.B. Namen, Vornamen, Wohnort, ... ). Unter Oracle Version 6 ist CHAR ein Synonym für VARCHAR,d.h. es wird platzsparend gespeichert. Unter Oracle 7 hingegen wird eine Zeichenkette des Datentyps CHAR immer auf die feste Länge n mit Leerzeichen erweitert und auch so gespeichert !
VARCHAR(n) wie CHAR(), wird aber platzsparend ge- speichert. Oracle arbeitet hier optimal: es wird nur der tatsächlich durch die Daten beanspruchte Platz benötigt. Daher kann man Felder, wenn nötig, unbedenklich als VARCHAR(254) (Maximallänge) definieren. Unter Oracle 7 gibt es für VARCHAR auch die Bezeichnung VARCHAR2, und die Maximallänge ist auf 2000 angestiegen.
LONG Sonderfall von VARCHAR: maximal 64KB (Oracle7 : 2GB) Text, zahlreiche SQL-Operationen sind jedoch später mit diesem Datentyp nicht möglich.
DATE dieser Datentyp sollte für Datumsangaben ( Geburtsdatum, Nachsorgetermin, ... ) verwendet werden. Ein Datum könnte man zwar auch in CHAR() abspeichern, aber als DATE kann man in SQL damit "rechnen", z.B. alle Patienten bestimmen, die innerhalb eines festgelegten Intervalles einen Nachsorgetermin haben.
NUMBER Oracle-Datentyp für eine beliebige Zahl mit oder ohne Nachkommastellen mit maximal ca. 38 geltenden Ziffern. Oracle speichert auch hier stets mit variabler Länge, damit platzsparend, so daß für eine Zahl immer NUMBER verwendet werden kann.
NUMBER(m,n) Oracle-Datentyp für eine beliebige Zahl der maximalen Gesamtlänge m mit maximal n Nachkommastellen. n und m müssen kleiner als ca. 38 sein.
Allgemeine numerische SQL-Datentypen
(können unter Oracle verwendet werden, werden aber intern in NUMBER umgesetzt)
INTEGER Große Ganzzahl bis ca. 2.000.000.000
SMALLINT Kleinere Ganzzahl, häufig bis ca. 32.000
FLOAT Gleitkommazahl, evtl. in exponential- (wissenschaftlicher) Schreibweise.

Für jede Spalte kann optional NOT NULL angegeben werden. Dann ist es nicht erlaubt, eine Zeile in diese Tabelle einzufügen, bei der diese Spalte keinen Wert hat.

Mit der fortschreitenden Verbreitung von Multimedia-Daten wurden weitere spezielle Datentypen eingeführt (z.B. BLOB - Binary Large OBject).


Beispiel :

Die Patiententabelle des GTDS könnte entstehen durch :

create Table PATIENT (
 Pat_ID                                   NUMBER(10),
 Name                                     VARCHAR(30),
 Vorname                                  VARCHAR(30),
 Titel                                    VARCHAR(30),
 Geburtsdatum                             DATE,
 Geschlecht                               VARCHAR(1),
 Sterbedatum                              DATE,
 Sterbe_Datum_exakt                       VARCHAR(1),
 Nationalitaet                            VARCHAR(3),
 Strasse                                  VARCHAR(30),
 PLZ                                      VARCHAR(6),
 Landeskennung                            VARCHAR(3),
 Ort                                      VARCHAR(30),
 Zustellbezirk                            VARCHAR(3),
 Telefon                                  VARCHAR(20),
 Sv_Nummer                                VARCHAR(20),
 Haupt_Vers_Name                          VARCHAR(30),
 Haupt_Vers_Vorname                       VARCHAR(30),
 Haupt_Vers_Geb_Dat                       DATE,
 Aenderungsdatum                          DATE,
 Fk_LeistungstraeIns                      VARCHAR(40),
 Fk_OrtstabelleOKZ                        VARCHAR(5),
 Fk_OrtstabelleOKZ0                       VARCHAR(10),
 Fk_BenutzerBenutze                       VARCHAR(10),
 Todesursache                             VARCHAR(1),
 Autopsie                                 VARCHAR(1),
 Tumortod                                 VARCHAR(1),
 Vorwahl                                  VARCHAR(10),
 Patienten_ID                             VARCHAR(30),
 Mitgliedsnummer                          VARCHAR(30)
)
/

Im Zuge ständiger logischer Erweiterungen hat dieses Kommando immer mehr Zusätze erfahren (z.B. für CONSTRAINTS, in Oracle8 für geschachtelte Tabellen usw.). Ferner können bei Oracle eine Reihe von Zusätzen angegeben werden, wo und in welcher Speicherstruktur die Tabelle abgelegt werden soll (TABLESPACE - Klausel, STORAGE() - Klausel). Darüber geben die SQL-Handbücher Auskunft. Trotzdem reicht die obige Syntax nach wie vor aus.


Index erstellen

CREATE INDEX <indexname>
 ON <tabellenname> ( <spaltenname> [, <spaltenname> , .... ] )

Beispiel :

CREATE INDEX patnumm ON patient ( pat_id ) ;

Erzeugt einen Index über die Spalte pat_id der Tabelle patient. Ein Index macht Suchoperationen über die verwendete Spalte schneller. Insbesondere für Join-Operationen (s.u.) oder Unterricht wirkt er beschleunigend. Andererseits verbraucht er Platz auf der Festplatte. Unterhalb einer Tabellengröße von 200 ... 1000 Datensätzen ( Zeilen ) ist es unnötig, einen Index zu errichten. Syntaktisch wird ein Index für kein sonstiges SQL- Statement benötigt.

SELECT-Statement


Dies ist das wichtigste SQL-Statement. Es erlaubt in vielfältigster Weise, Daten aus einer Datenbank zu gewinnen, zu ordnen, zu formatieren usw.. Letztlich können an dieser Stelle die ungeheuer vielfältigen Möglichkeiten nur angedeutet werden.

Es wird versucht, schrittweise einige Möglichkeiten vorzustellen :

1. Einfaches Select

SELECT <spaltenname,....|*> FROM <tabellenname> [ WHERE <BEDINGUNG> ]
Beispiele :
select * from PATIENT ;
Liefert alle Datensätze der Tabelle patient, vollständig, in Form einer Ergebnistabelle. select Pat_ID, Name, Vorname from PATIENT ;
liefert aus allen Datensätzen/Zeilen der Tabelle patient die gewünschten Spalten.

Hinter SELECT können also entweder die gewünschten Spalten, getrennt durch Komma, oder * für "alle Spalten der gewünschten Tabelle angegeben werden.
select * from PATIENT where Pat_ID = 10 ;
Liefert aus der Tabelle patient nur den Pat. mit der Nummer 10. Dies ist das erste Beispiel einer BEDINGUNG bei der Suche.


Als  BEDINGUNG in der WHERE-Klausel sind u.a. möglich :
<spaltenname>  =  <wert>  {Gleichheit}
               !=         {nicht gleich}
               >
               <
               >=
               <=
               in ( <wert1>, <wert2> , ... )
                       {Übereinstimmung mit einem Wert}

<spaltenname>  BETWEEN <wert1> AND <wert2>

<spaltenname> LIKE  <wert>
	<wert> kann dabei Jokerzeichen enthalten :
		%   für beliebig viele unbek. Zeichen
		_   für ein  Zeichen

Bei der Angabe von <wert> müssen Zeichenketten in einfache Anführungszeichen eingeschlossen werden (also z.B. 'Schmidt' ). Beim Vergleich wird im Gegensatz zu Tabellen- und Spaltennamen zwischen Groß- und Kleinschreibung unterschieden. Zahlen ( z.B. Patientennummer ) können dagegen ohne weitere Vorkehrungen angegeben werden.

Für den Vergleich, ob Felder leer sind, muß die Klausel IS NULL verwendet werden, sonst wird nichts gefunden.

weitere Beispiele :
select Name, Vorname, Geburtsdatum from PATIENT
where Name != 'Schmidt' ;
select Name, Vorname, Geburtsdatum from PATIENT
where Geburtsdatum BETWEEN '11-JAN-11' AND '12-DEC-12' ;

ACHTUNG : Syntax und Semantik in Verbindung mit dem Datentyp DATE sind in Datenbanken nicht einheitlich geregelt. Unter Oracle gilt der Grundsatz, daß DATE-Felder normalerweise ohne Konversion benutzt werden können, wenn man das Oracle-Standard-Datumsformat DD-MON-JJ verwendet (wie oben gezeigt). In jedem anderen Falle müssen die Umsetzungsfunktionen to_date() bzw. to_char() verwendet werden. ( Beispiel aus einer anderen Datenbank: in dBaseIV muß es heißen : SELECT name, vorname, geburtsdatum FROM patient WHERE geburtsdatum BETWEEN CTOD('11.11.1911') AND CTOD('12.12.1912');)

Beispiele:
select TO_CHAR(Geburtsdatum,'DD.MM.YYYY') from PATIENT;
gibt die Geburtsdaten deutsch formatiert aus, und
select Name, Vorname from PATIENT
where Geburtsdatum = TO_DATE('11.11.1911','DD.MM.YYYY');
selektiert alle am 11.11.11 geborenen Patienten. Die allgemeine Syntax ist :
- TO_CHAR( <Datum>, '<Format>')  bzw.
- TO_DATE( <Zeichenkette>, '<Format>')

[ weitere Informationen zur Datumsdarstelllung unter Oracle V.7 und 8 ]

Beispiel zu LIKE :
select Name, Vorname, Geburtsdatum from PATIENT
where Name like 'M%er' ;
Findet alle Name, die mit 'M' beginnen und mit 'er' enden, z.B. Meyer, Maier, Meier, .. aber auch Mellenburger !

Mehrere Bedingungen können mit den Operatoren AND und OR verknüpft werden, z.B:

select Name, Vorname, Geburtsdatum from PATIENT
where Name = 'Schmidt'
  AND Vorname = 'Hans' ;
Bedingungen wie BETWEEN oder LIKE können mit dem Operator NOT umgekehrt werden.

SQL-Funktionen

Neben den bereits erwähnten Datumsfunktionen verfügt Oracle-SQL über eine Fülle von nützlichen Funktionen, die die Möglichkeiten der Daten -Findung und -Darstellung beträchtlich erweitern. [ kurze Übersicht zu Funktionen in Oracle-SQL ]
In manchen anderen Datenbanken sind nur wenige Funktionen verfügbar.

ORDER BY Klausel

Die Ergebnisse einer Abfrage können nach einer oder mehreren Spalten der Ergebnistabelle sortiert werden. Die Syntax des einfachen SELECT erweitert sich damit zu :


SELECT <spaltenname,....|*> FROM <tabellenname>
[ WHERE  <BEDINGUNG> ]
[ ORDER BY <spalte,...> ]
Beispiel :
 
select Name, Vorname, Geburtsdatum from PATIENT
where Name != 'Schmidt'
order by Name, Vorname ;
Stattdessen ist meist auch möglich :
 
select Name, Vorname, Geburtsdatum from PATIENT
where Name != 'Schmidt'
order BY 1,2 ;
/* Spalten in der Reihenfolge oben hinter SELECT numeriert */


Subquery in der Where-Klausel


Eine Where-Klausel kann auf das Ergebnis eines anderen Select- Statements Bezug nehmen.

Beispiel :
 
select * from PATIENT
where Pat_ID in (
 select Fk_PatientPat_id from TUMOR 
 where Aenderungsdatum >= '01-JAN-94')
Listet die Stammdaten aller Patienten auf, deren Diagnosedaten (Ersterhebung) seit dem 1.1.94 verändert wurden. Mögliche Lösungen für SQL-Abfragen mit Subquery sind :
 
SELECT <Spaltenliste|*> FROM <Tabelle,...>
WHERE <wert> [ NOT ] in ( <Select-Statement> )
[ AND|OR <weitere Bedingung> ]
oder
 
WHERE <wert> = <ALL|ANY> ( <Select-Statement> )
oder (Exists-Abfrage, wichtige Sonderform!)
 
WHERE EXISTS ( SELECT * FROM <tabelle2> where <bedingung>)

Die letzte Form fragt ab, ob ein Satz der tabelle2 existiert, der bedingung genügt. In bedingung können Spalten aus der Hauptabfrage vorkommen (korrelierende Subquery).

2. Select über mehrere Tabellen ( Join - Select )

Mit dem SELECT-Statement können Daten aus mehreren Tabellen auf einmal gesucht werden. Der wichtigste Fall ist dabei der, daß die Daten aus beiden Tabellen über einen gemeinsamen Schlüssel einander zugeordnet werden können ( der typische Aufbau einer relationalen Datenbank ).

Beispiel: In der Tumor-Datenbank gehören diejenigen Datensätze der Tabellen patient und tumor zusammen, die die gleiche pat_id haben. In der Tabelle tumor stehen die Tumoren zu einem Patienten unter seiner Id-Nummer. Die Daten wurden auf mehrere Tabellen verteilt, da zu einem Patienten keine, eine oder mehrere Tumoren gehören können (1 : n -Beziehung). Die Zusammenführung der Daten erfolgt durch

 
select Name, Vorname, Tumor_ID, Diagnosetext
 from PATIENT , TUMOR
where PATIENT.Pat_ID = TUMOR.Fk_PatientPat_ID ;

Spaltennamen wie fk_patientpat_id wurden bei der Erstellung des Datenmodells von einem CASE-Tool generiert. Sie deuten an, daß die pat_id in der Tabelle tumor die Funktion eines Fremdschlüssels hat.

Die WHERE-bedingung ist hier zwingend notwendig. Anderenfalls würden die Datensätze nicht "zusammengeführt". Stattdessen würde SQL ein kartesisches Produkt bilden, d.h. jeden Satz der patient -Tabelle mit jedem Satz der tumor -Tabelle kombinieren. Sind die Spaltennamen nicht eindeutig (in mehreren unterschiedlichen Tabellen können Spalten mit gleichen Namen sein), so kennzeichnet man die Spalten durch tabellenname.spaltenname (wie oben in der Where-Bedingung, wo es allerdings nicht unbedingt notwendig wäre).

Allgemeine Syntax :
 
SELECT <spaltenname,....|*> FROM <tabellenname,tabellename, ...>
WHERE  <JOIN-BEDINGUNG>
[ AND <BEDINGUNG>, ... ]

Diese Art Select wird als Join bezeichnet. Sogar ein Join über mehrere Tabellen ist möglich. Will man dabei alle Spalten einer Tabelle , so kann man sie in der Form tabellenname.* angeben.

Beispiel :
 
select PATIENT.Name, Tumor_ID, Diagnosetext, ARZT.Name
 from PATIENT , TUMOR, ARZT
where PATIENT.Pat_ID = TUMOR.Fk_PatientPat_ID
  AND TUMOR.Fk_ArztArzt_ID = ARZT.Arzt_ID
order by PATIENT.Name ;

Liefert die Patienten, ihre Tumoren und die Ärzte, die diese Daten lieferten.

Hier wird ein besonderes Problem des Join-Selects deutlich : nicht zu allen Dokumenten ist ein Arzt als Quelle angegeben. In der oben gezeigten Form wird dann das ganze Dokument unterdrückt. Um in dem Falle, daß nur eine Untertabelle eines Joins keinen Wert liefert, den restlichen Datensatz anzeigen zu können, gibt es den outer join . Er wird in Oracle durch (+) hinter der Spalte, die möglicherweise keinen Wert liefert, angefordert. Hat dann die zugehörige Tabelle keinen passenden Wert, wird für alle ihre Spalten im entstandenen Datensatz nichts angezeigt.

Beispiel :
select PATIENT.Name, Tumor_ID, Diagnosetext, ARZT.Name
 from PATIENT , TUMOR, ARZT
where PATIENT.Pat_ID = TUMOR.Fk_PatientPat_ID
  AND TUMOR.Fk_ArztArzt_ID = ARZT.Arzt_ID(+) /* <------ */
order by PATIENT.Name ;

Jetzt werden in diesem Beispiel alle Patienten und ihre Tumoren angezeigt, nicht nur die, von denen ein Arzt als Quelle der Daten bekannt ist.

Sobald in einem SQL-Statement mehrere Tabellen vorkommen, könnten Spalten aus verschiedenen beteiligten Tabellen den gleichen Namen haben (z.B. hier Spalte Name in den Tabellen PATIENT und ARZT). Dann ist es notwendig, klarzustellen welche Spalte aus welcher Tabelle kommt. Dazu setzt man vor den Spaltennamen, abgetrennt durch einen Punkt, den Namen der Tabelle (siehe z.B. PATIENT.Name). Bei längeren Tabellennamen kann das lästig sein. Daher erlaubt Oracle, bei den Tabellen kurze Aliasnamen zu vergeben und diese dann innerhalb des Statements anstelle des Tabellen-Namens zu verwenden. Das obige Statement könnte dann so geschrieben werden :

select P.Name, T.Tumor_ID, T.Diagnosetext, A.Name
 from PATIENT P , TUMOR T, ARZT A
where P.Pat_ID = T.Fk_PatientPat_ID
  AND T.Fk_ArztArzt_ID = A.Arzt_ID(+) /* <------ */
order by P.Name ;

In einem solchen Falle ist es dann leicht, zusätzliche Klarheit zu schaffen indem alle Spalten in der Select-Liste einen Tabellen-Präfix erhalten.

3. Gruppenbildung und -funktionen



SELECT <spaltenname,....|*> FROM <tabellenname>
[ WHERE  <BEDINGUNG> ]
[ GROUP BY <spaltenname> ]
[ HAVING <BEDINGUNG> ]

Im Select können eine Reihe von Summen- und Gruppenfunktionen eingesetzt werden. Die einfachste ist COUNT(*). Sie zählt die zutreffenden Zeilen.

Beispiele :
select COUNT(*) from PATIENT ;
zählt die Zeilen in der Tabelle patient.
select Geschlecht, COUNT(*) 
from PATIENT
group by Geschlecht ;

ergibt die Anzahl pro Geschlecht in der Tabelle patient. weitere Gruppenfunktionen stehen zur Verfügung :

 
COUNT (DISTINCT <Spaltenname>)
          Anzahl der Zeilen mit verschiedenen Werte einer Spalte
MAX ( <Spaltennname> )          Höchster Wert einer Spalte
MIN ( <Spaltennname> )          Niedrigster Wert einer Spalte
AVG ( <Spaltennname> )          Durchschnittswert einer Spalte
SUM ( <Spaltennname> )          Summe über eine Spalte
Beispiel :

select MAX( Geburtsdatum ) from PATIENT ;
ermittelt den jüngsten Patienten
select AVG( Gewicht ), Lokalisat 
from ERST /* keine GTDS-Tabelle */
group by Lokalisat ;
ermittelt das durchschnittliche Gewicht der Patienten bei der Ersterhebung, gruppiert nach Tumorlokalisationen. Bei der Verwendung solcher Funktionen in Verbindung mit GROUP BY ist folgende Grundregel zu beachten :
 
   Alle Spaltennamen, die außerhalb der Zähl- und
   Zustandsfunktionen in der <Spaltenliste> auftauchen, müssen
   auch in der GROUP BY -Klausel stehen.
Die HAVING -Klausel verlangt zusätzlich, daß nur Gruppen angezeigt werden, die <Bedingung> genügen. Dieses Thema wird evtl. noch im Unterricht ausführlicher behandelt.

Ein VIEW erzeugen - "gespeicherte Abfrage"

Mit

create View <ViewName> AS <Select-Statement>

wobei Select-Statement im Prinzip eine beliebige, gültige Select-Anweisung sein kann, kann eine Abfrage gewissermaßen "gespeichert" werden und steht dann wie eine Tabelle zur Verfügung.
Beispiel : nach

create View KURZDIAGNOSEN AS 
select P.Name,T.DiagnoseText
from  PATIENT P, TUMOR T
where P.Pat_ID = T.Fk_PatientPat_ID ;
ist es möglich, mit SQL> DESC KURZDIAGNOSEN die beiden Spalten des View aufzulisten, und mit select * from KURZDIAGNOSEN ; erhält man eine Auflistung von Name und Diagnosetext. Oracle hat aber nur die Abfrage für das View dauerhaft gespeichert und holt die Daten bei jeder Query auf das View aus den originalen Tabellen.



INSERT-Statement

Dieses Statement dient dazu, Daten in eine Tabelle einzufügen.

Syntax :
(1)
INSERT INTO <tabellenname> [ ( <Spaltenname,...> ) ]
VALUES ( <Wert1,...> )
Die Angabe von Spaltennamen ist dann überflüssig, wenn für jede Spalte der Tabelle ein Wert angegeben wird.
Beispiele :
 
     insert into HAUSARZT /* keine GTDS-Tabelle */ Values
     ( 'Mümmel', 'Fritz', 'Heinertstr. 1', 8765, 'Olm', 99 ) ;
Wie bei der Where-Klausel müssen Zeichenketten in Anführungs- zeichen stehen, Zahlen nicht. Datumswerte müssen bei Oracle im Standardformat DD-MON-YY in einfachen Anführungszeichen angegeben oder mit TO_DATE() umgewandelt werdem.
     insert into ARZT ( Arzt_ID, Name )
     Values ( 999, 'Hampelmann' ) ;

Die meisten Datenbanksysteme verfügen heute über einen sog. Maskengenerator, so daß die Eingabe einzelner Datensätze viel einfacher über Bildschirmmasken geschehen kann. Unter Oracle ist SQL*Forms der Maskengenerator.

Syntax (Format 2)
 
INSERT INTO <tabellenname> [ ( <Spaltenname,...> ) ]
<SELECT - Statement>

Dies ist die wohl nützlichere Form des Insert-Statements. In die betroffene Tabelle werden mittels Select Daten aus einer anderen Tabelle eingefügt. Angenommen, es gäbe eine weitere Ärzte-Tabelle hausarzt mit den Spalten arztnr , nname, ort so könnten diese Ärzte in die Tabelle arzt übernommen werden mit dem Statement :

   insert into ARZT ( Arzt_id, Name, Ort )
   select Arztnr, Nname, Ort from HAUSARZT ;



UPDATE-Statement

Syntax :
UPDATE <tabellenname>
SET <spalte> = <wert>, [ <spalte2> = <wert>, ... ]
[ WHERE <BEDINGUNG> ]
Die WHERE-Klausel ist wie bei SELECT zu verstehen.

Damit kann man einzelne Spalten einer Tabelle in den durch die where-Klausel spezifizierten Zeilen ändern. Fehlt die where- Bedingung, werden alle Zeilen der Tabelle geändert . Soweit dies nur einzelne Zeilen betrifft, wird man wohl auch hier, wie bei Insert (s.o.), eher eine Bildschirmmaske, wie sie mit einem Maskengenerator schnell bereitgestellt werden kann, verwenden.Dagegen ist das Update-Statement sinnvoll, wenn eine größere Anzahl Spalten gleichsinnig geändert werden soll. Das sinnigste Beispiel hierzu stammt aus dem kaufmännischen Bereich. Eine Preissenkung in einer Artikeltabelle könnte bewirkt werden durch :

     update Artikel SET Preis = ( Preis * 0.95 ) ;
Damit würden alle Preise um 5% gesenkt !

DELETE-Statement

Syntax :

DELETE FROM <tabellennname>
[ WHERE <BEDINGUNG> ]
Die WHERE-Klausel ist wie bei SELECT zu verstehen. Es werden die Zeilen gelöscht, die der WHERE-Bedingung genügen, d.h. die bei einem SELECT mit gleicher WHERE-Klausel angezeigt würden. ACHTUNG : Fehlt die WHERE - Bedingung, werden alle Daten einer Tabelle gelöscht !

Transaktionsbearbeitung


Mit INSERT, UPDATE und insbesondere DELETE Statements wird die Datenbank direkt verändert. Nach der Ausführung sind die Ergebnisse, die neuen, veränderten Inhalte jedoch noch in einem "nicht endgültig" - Status. Die veränderten Inhalte sind für den, der sie ausgeführt hat, schon sichtbar (z.B. bei einem SELECT), andere dagegen, die Rechte auf die gleiche Tabelle haben, erhalten noch die alten Inhalte angezeigt. Erst mit

 
COMMIT [WORK] ;
werden die Änderungen endgültig freigegeben und in der Datenbank festgeschrieben. (Schlüsselwort WORK ist unter Oracle optional, braucht nicht eingegeben zu werden). Stattdessen könnten Sie jedoch auch Ihre Meinung ändern und mit
 
ROLLBACK [WORK] ;
alle Änderungen (INSERT, UPDATE und DELETE) seit dem letzten COMMIT oder dem Aufruf von sqlplus bzw. sqldba rückgängig machen. Diese Möglichkeit ist besonders wichtig bei Änderungen oder Statements, bei denen man sich zunächst seiner Sache nicht ganz sicher ist, oder wenn mehrere Vorgänge nur entweder zusammen oder gar nicht ausgeführt werden dürfen (klassisches Beispiel : Buchung). Wenn Sie sqlplus ohne explizites COMMIT verlassen, führt sqlplus automatisch ein sog. implizites COMMIT aus. Zu einem impliziten COMMIT führen auch alle Datendefinitions-Statements, also alle CREATE- , DROP- , ALTER- und einige weitere Statements. In diesem Falle ist kein Rollback der letzten Änderungen mehr möglich.



Zugriffsrechte bei mehreren Benutzern einer SQL-Datenbank


Rechte werden mit GRANT vergeben und mit REVOKE widerrufen. Die Zugriffsmöglichkeiten innerhalb einer Datenbank sind abhängig von

Globale Benutzerrechte unter Oracle 6


Wenn ein Oracle-Benutzer eingerichtet wird, können ihm drei Stufen von Rechten vergeben werden :
CONNECT
Darf sich auf der Datenbank einloggen, auf Objekte (Tabellen, Views, usw.), auf die er Zugriff hat, zugreifen (SELECT usw.), jedoch keinerlei neue Tabellen oder sonstige Objekte kreieren.
RESOURCE
Darf sich auf der Datenbank einloggen, auf Objekte (Tabellen, Views, usw.), auf die er Zugriff hat, zugreifen (SELECT usw.), und im Rahmen des ihm zugewiesenen Platzkontingents neue Tabellen oder sonstige Objekte kreieren.
DBA
Datenbankverwalter-Privileg. Darf auf alle Objekte zugreifen, neue kreieren, existierende löschen (von beliebigen Benutzern!) oder verändern. Das DBA-Recht sollte daher nur an wenige Benutzer vergeben werden.
Unter Oracle 7 bieten sich hier durch Verwendung von sog. ROLES und PROFILES viel mehr Möglichkeiten. Diese sind jedoch auch viel komplexer ... Zur Erhaltung der Kontinuität sind die Privileg-Stufen CONNECT / RESOURCE / DBA also Rollen vorhanden

Ein Benutzer mit DBA-Privileg ist erforderlich, um einen neuen Oracle-Benutzer anzulegen. Dies geschieht in seiner elementarsten Form durch z.B.

     /* ORACLE VERSION 6 */
     GRANT CONNECT TO SCOTT IDENTIFIED BY TIGER ;
     /* Teilt dem Benutzer SCOTT das CONNECT-Recht zu.*/
     GRANT CONNECT, RESOURCE TO OPS$TUMSYS IDENTIFIED BY HIHI ;

     /* ORACLE VERSION 7 und evtl. 8 */
     CREATE USER OPS$TUMSYS IDENTIFIED BY DUMM ;
     /* Rechte werden separat vergeben */
     GRANT RESOURCE TO OPS$TUMSYS ;

Teilt dem Benutzer OPS$TUMSYS das RESOURCE-Recht zu. Da es ein OPS$-Account ist, gibt es danach folgende Möglichkeiten des Zugangs :

Wird ab Oracle7 ein neuer Benutzer erzeugt, sollten die Möglichkeiten zur differenzierten Rechtevergabe genutzt werden. Wie dies für den GTDS-Administrator OPS$TUMSYS aussehen könnte, zeigt das beigelegte Beispiel user_acc7c.sql


Benutzerrechte für einzelne Objekte


Diese Rechte werden mit GRANT vergeben in der Form
GRANT <Recht,Recht,...> ON <Objekt> TO <Benutzer>
z.B.
 GRANT SELECT, INSERT,UPDATE ON TUMOR TO OPS$HANS ; 
Wenn ein Recht an alle vergeben werden soll, kann man dazu den Pseudo-Benutzer PUBLIC benutzen :
 GRANT SELECT  ON ORTSTABELLE TO PUBLIC ; 
erlaubt allen den lesenden (SELECT) Zugriff auf die Ortstabelle. Mit GRANT vergebene Rechte können mit REVOKE widerrufen werden. Weitere Auskunft über die Benutzerrechte geben die Abschnitte über GRANT bzw. REVOKE im SQL-Referenzhandbuch von Oracle.

Einige Sätze zum Datenaustausch unter Oracle


Will man Daten aus der Oracle-Datenbank für andere Systeme ausgeben (z.B.dBase), so muß man von Hand mit SQL*Plus oder SQL*ReportWriter über geeignete SQL-Statements das passende Format erzeugen (etwas schwieriger als das simple UNLOAD-Statement von Informix).

Zum Einladen von Textdateien steht der SQL*Loader zur Verfügung. Dieses nicht unbedingt einfach zu bedienende Werkzeug ist in PartII des RDBMS Utilities User's Guide beschrieben. Es muß eine Beschreibungsdatei mit Befehlen für den Ladevorgang erstellt werden. Hat man jedoch Oracle RDBMS für PC und will dBase-Dateien laden, wird diese Aufgabe von dem Werkzeug DB3PREP erleichtert. Zum Datentransfer zwischen zwei Oracle-Datenbanken, auch auf völlig verschiedenen Rechnersystemen, stehen die im RDBMS Utilities User's Guide beschriebenen Werkzeuge Export und Import zur Verfügung. Ihre Bedienung ist recht einfach (s.u.). Es ist jedoch nur reiner Datentransfer (einschl. bestimmter Zeichensatz- konvertierungen, etwa von EBCDIC nach ASCII ) möglich. Das externe Format dieser Werkzeuge ist nicht sinnvoll von anderen Programmen lesbar. Auch als Archi- vierungswerkzeuge ist ihr Nutzen begrenzt, da spätere Versionen von Oracle evtl. alte Export-Files nicht mehr lesen können. Es folgt eine Beispielsitzung :
Export aller Tabellen von OPS$TUMSYS unter der Vorrausetzung, daß man unter Unix bzw. Novell als tumsys eingeloggt ist:


exp userid=/ file=tumsys grants=y

Es werden alle Tabellendefinitionen und -inhalte in eine Datei tumsys.dmp geschrieben. Ihr prinzipieller Inhalt kann mit

imp / SHOW=Y file=tumsys

angeschaut werden. Das Wiedereinlesen geschähe ebenfalls mit imp . Mit imp help=y bzw. exp help=y bekommt man Syntaxhilfe für die Kommandozeilen.

[Teil 2]

[Anfang] [voriger Abschnitt] [nächster Abschnitt]

Funktionen in Oracle(®)-SQL

Eine Funktion ist das, was die Kaffeemaschine für den guten Kaffee darstellt - da schütten Sie oben Pulver und Wasser hinein, und unten kommt der Kaffee heraus. Genauso übernimmt eine Funktion einen oder mehrere Werte, und etwas anders entsteht durch die Bearbeitung innerhalb der Funktion.

Zunächst nun eine Übersicht :

Die Argumente der Funktionen werden symbolisch dargestellt. Dort bedeutet

string
eine allgemeine Zeichenkette. Das kann entweder ein Literal sein, wie etwa 'Dooof' oder der Name einer Spalte.
datum
ein Datum, wiederum entweder eine Zeichenkette im richtigen Format oder eine Datenbankspalte
number
entsprechend eine Zahl
Bitte beachten Sie insbesondere hinsichtlich Wiederholungen und optionaler Argumente die Konventionen im Hauptskript. Dementsprechend sind also Werte in Winkelklammern (< >) eingeschlossen, optionale Teile in eckige Klammern ( [ ] ).

Funktionen für einzelne Datensätze

Typische Zeichenketten-Funktionen
SUBSTR(<string>, <Pos> [,<Laenge>])   Gibt <Laenge> Zeichen ab Position <Pos> in <string> aus. Die Position wird ab 1 gezählt. Ist Laenge weggelassen, wird alles ab Position <Pos> gezeigt. Ist <Pos> größer als die Länge von <string>, wird NULL zurückgegeben.
LENGTH(<string>) Gibt die Länge von <string> in Zeichen aus.
UPPER(<string>) Gibt <string> in GROßBUCHSTABEN umgewandelt aus.
LOWER(<string>) Gibt <string> in kleinbuchstaben umgewandelt aus.
INITCAP(<string>) Wandelt jeweils den ersten Buchstaben von Wörtern in <string> in Großbuchstaben um.
RPAD(<string>, <Gesamtlaenge>[,<string2>]) bzw. LPAD(<string>, <Gesamtlaenge>[,<string2>]) Fügt an <string> so oft <string2> oder Leerzeichen (wenn weggelassen) auf der linken (LPAD) bzw. rechten (RPAD) Seite an, bis <Gesamtlaenge> erreicht ist.
LTRIM(<string> [,<string2>]) bzw. RTRIM(<string> [,<string2>]) Ist kein zweites Argument angegeben, wird <string> auf der linken (LTRIM) bzw. rechten (RTRIM) Seite von Leerzeichen befreit. Anderenfalls versucht Oracle solange auf der entspr. Seite vom Ende aus <string2> zu entfernen, bis es auf eine Zeichenkette trifft, die <string2> nicht entspricht.
DUMP(<string> [,<art> [,<start> [,<lang>]]]) Gibt <string> in einem komplett sichtbaren Format aus. Ist <art> 16, so entsteht ein "Hexdump". Klärt den Inhalt von Datenbankspalten, wenn unsichtbare Zeichen darin vermutet werden.
CHR(<number>) und ASCII(<string>) liefert das ASCII-Zeichen Nummer <number> (Funktion CHR()) bzw. die ASCII-Nummer des ersten Zeichens in <string> (Funktion ASCII())
INSTR(<string>,<string2> [,<pos> [,<vorkommen>]]) Suchfunktion - Gibt die Position von <string2> innerhalb von <string> aus. So würde INSTR('DOOF','OO') beispielsweise 2 finden (Position von 'OO' in 'DOOF'). Ist <pos> angegeben, wird erst ab da gesucht (-1 bedeutet rückwärts ab Ende suchen). Der letzte Parameter <vorkommen> erlaubt es, auch das 2., 3. usw. Vorkommen von <string2> zu finden.
REPLACE(<string>, <such> [,<ersetz>]) Gibt <string> aus, wobei alle Vorkommen von <such> durch <ersetz> ersetzt sind. Fehlt <ersetz>, werden alle Vorkommen von <such> in <string> gelöscht.
TRANSLATE(<string>, <von> , <nach> ) Im Gegensatz zu REPLACE() zeichenweise Ersetzung. Im Ergebnis ist jeder Buchstabe, der in <von> vorkommt durch den entsprechenden Buchstaben in <nach> ersetzt. Enthält <nach> weniger Buchstaben als <von> , so werden die Buchstaben aus <von> ohne Entsprechung in <nach> gelöscht. <nach> muß aber mindestens einen Buchstaben enthalten, sonst ist das Ergebnis immer NULL.
DECODE( <Spalte>, <wert1>, <ersatz1>, <wert2>, <ersatz2>, .... , <defaultwert> ) Diese außerordentlich mächtige SQL-Funktion findet sich nur bei Oracle. Sie erlaubt es, einzelne Werte aus der Datenbank durch jeweils andere zu ersetzen, und noch einen default-Wert zu benennen.
GREATEST( <Wert1> , <Wert2> [, <Wert3>] ...) Liefert von den mehreren Werten den größten zurück (analog liefert LEAST() den kleinsten). Funktioniert mit Zeichen- oder numerischen Spalten, mit Datumswerten nur, wenn sie mit TO_DATE() konvertiert werden.
Ersetzung von NULL-Werten
NVL(<Wert>,<Ersatz>) Wenn <Wert> einen Inhalt hat (SQL-mäßig : Wert IS NOT NULL ), wird <Wert> genommen, wenn nicht dann <Ersatz>. <Wert> kann vom Typ CHAR, VARCHAR2, NUMBER, DATE usw. sein ; der Ersatzwert muß einen passenden Datentyp haben.
Konversion von Datentypen
TO_CHAR( <Datum>, '<Format>') bzw. TO_DATE( <Zeichenkette>, '<Format>') Konvertiert Datum in (darstellbare) Zeichenkette gemäß Format bzw. umgekehrt. Wird im Artikel über Datumsformate ausführlich behandelt.
TO_CHAR(<number> [,format]) bzw. TO_NUMBER(<string> [,<format> ]) Konvertiert Zahl in darstellbare Zeichenkette bzw. umgekehrt. Da Oracle diese Konversion in vielen Fällen automatisch durchführt, sind diese Funktionen und insbesondere das Format (über welches Handbücher oder Online-Hilfe Auskunft geben) weniger essentiell als die Datumsfunktionen. TO_CHAR() sieht gleich aus wie die entsprechende Datumsroutine ; es bestimmt aus seinen Argumenten, welche Konversion benötigt wird.
Numerische Funktionen (im weiteren Sinne)
ROUND(<num> [,<stellen>]) und TRUNC(<num> [,<stellen>]) Diese Funktionen dienen zum Runden bzw. Abschneiden von Zahlen auf <stellen> Nachkommastellen. Sie können jedoch auch auf Datumswerte angewandt werden, wobei dann die (ja immer vorhandene) Uhrzeit auf den Anfang des Tages (TRUNC()) bzw. Mittag 12:00 (ROUND()) gesetzt wird. Es besteht dabei sogar die Möglichkeit, Datumsformate anstelle von <stellen> einzusetzen und etwa Geburtsdaten auf ganze Jahre zu runden / anonymisieren.
Von den gebräuchlichen mathematischen Funktionen stehen zumindest folgende unter Oracle zur Verfügung :
ABS, CEIL, COS, COSH, EXP, FLOOR, LN, LOG, MOD, POWER, SIGN SIN, SINH, SQRT, TAN, TANH
Die Genauigkeit beträgt bis zu 36 Stellen. Die vier Grundrechenarten können unmittelbar in SQL-Statements verwendet werden ( select 2 * 2 Ergebnis from DUAL; zeigt das Ergebnis 4 )


Summen- und Gruppenfunktionen

beziehen sich entweder auf alle Zeilen einer Tabelle oder Gruppen, die durch die GROUP BY Klausel gebildet werden. Bis auf wenige Ausnahmen (MIN MAX etwa ) sind sie sinnvoll nur für numerische Spalten zu verwenden.
wichtige Summen- und Gruppenfunktionen
MIN(<Wert>) und MAX(<Wert>) liefert den kleinsten bzw. größten Wert der betreffenden Spalte in den ausgewählten Zeilen. Funktioniert mit Zeichen- , numerischen und Datumsspalten.
COUNT(*) liefert die Anzahl betroffener Zeilen ohne Einschränkung
COUNT( <Spalte> ) liefert die Anzahl betroffener Zeilen , in denen der Wert von <Spalte> nicht leer (NULL) ist.
COUNT( DISTINCT <Spalte> ) liefert die Anzahl betroffener Zeilen mit verschiedenen, nicht leeren Werten (Anzahl verschiedener Werte).
AVG( <Spalte> ) Liefert den arithmetischen Mittelwert für alle Zeilen, wo <Spalte> nicht leer (NULL) ist.
SUM( <Spalte> ) Liefert die Summe für alle Zeilen, wo <Spalte> nicht leer (NULL) ist.
VARIANCE( <Spalte> ) bzw. STDDEV( <Spalte> ) Liefern statistische Größen für alle Zeilen, wo <Spalte> nicht leer (NULL) ist.

[Teil 3]

[Anfang] [voriger Abschnitt] [nächster Abschnitt]

Darstellung von Datum und Uhrzeit unter Oracle7(®)

  1. "klassisches" default-Format
  2. Datumsformatierung mittels Funktionen
  3. default-Format ändern bei Oracle7

Während die äußere Darstellung sehr verschieden aussehen kann, speichert Oracle7 Zeitinformationen, also Datum und Uhrzeit, intern in Tabellen-Spalten des Datentyps DATE immer im gleichen Format. Dieses Format umfaßt 7 Bytes, es ist immer Datum und sekundengenaue Uhrzeit enthalten, und es können maximal Zeiten zwischen ca. 4712 v.Chr. und 4712 n.Chr. dargestellt werden.

Soll nun eine Tabellen-Spalten des Datentyps DATE dargestellt werden (z.B. für ein eine Select-Anweisung in SQLPLUS), so wird sie in ein äußeres Format zur Darstellung konvertiert. Dabei gibt es ein default-Format und andererseits die Möglichkeit, andere Formate zu wählen.

klassisches default-Format

[ zurück]

Bei älteren Oracle-Versionen war das default-Format gewöhnlich DD-MON-YY :

  1  select Name, Geburtsdatum from PATIENT
  2  where Geburtsdatum IS NOT NULL
  3*   AND Rownum < 10
SQL> /

NAME                           GEBURTSDA
------------------------------ ---------
Testele                        12-MAY-67
G2Testcc                       12-JUN-67
Schoenholz                     11-NOV-11
Testelen                       12-JUN-57
Altmann                        01-FEB-58
Janssen                        10-OCT-07
Schmidt                        11-FEB-96
Schmidt                        11-NOV-70
Kirschberger                   11-FEB-68

9 rows selected.

Dieses Format dürfte allen Oracle-Anwendern bestens bekannt sein.

Soll ein Datum in einer where-Klausel verwendet werden, muß es, wenn nicht die passenden Funktionen zum Einsatz kommen, das default-Format haben :

  1  select Name, Geburtsdatum from PATIENT
  2  where Geburtsdatum = '11-NOV-11'
  3*   AND Rownum < 10
SQL> /

no rows selected 

Das lange Zeit übliche default-Format von Oracle besteht also aus einem zweistelligen Tag, dann dem (gewöhnlich englischen) Monats-Kürzel mit drei Buchstaben und dem zweistelligen Jahr, welches im aktuellen Jahrhundert angenommen wird. Demnach bedeutet also 11-NOV-11 derzeit den 11. November 2011.

Datumsformatierung mittels Funktionen

[ zurück]

Mittels der Oracle-Funktionen TO_CHAR() und TO_DATE() ist es jedoch möglich, nahezu beliebige andere Formate zu erzeugen bzw. zu akzeptieren. Die grundsätzliche Syntax ist

- TO_CHAR( <Datum>, '<Format>')  bzw.
- TO_DATE( <Zeichenkette>, '<Format>')

Einige typische Formate wären
Oracle-Datumsformate
Format Bemerkung Beispiel "echtes" Datum
DD-MON-YY altes default-Format 25-FEB-98 25.2.2098
04-SEP-00 4.9.2000
DD.MM.YY deutsches Format 2-stell. Jahr, auf Kurs-PC 25.02.98 25.2.2098
04.09.00 4.9.2000
DD.MM.YYYY deutsches Format 4-stell. Jahr 25.02.1998 25.2.1998
04.09.2000 4.9.2000
DD.MM.YYYY HH24:MI:SS 4-stell. Jahr und Uhrzeit : Kursbeginn 4.9.2000 10:15:00 4.9.2000 10:15:00
YYYYMMDDHH24MI 4-stell. Jahr und Uhrzeit : Kursbeginn nach Größe unmittelbar hintereinander 200009041015 4.9.2000 10:15
MM/YYYY nur Monat und Jahr 9/2000 1.9.2000
zur Jahrtausendwende : "relative" Formate
Um die Datumseingabe vor und nach der Jahrtausendwende zu erleichtern, wurden "relative" Formate geschaffen. Beim Jahr ist jetzt statt "YY" möglich "RR" zu verwenden. Dann werden Jahreszahlen von 51-99 im vergangenen Jahrhundert gezählt, 0-49 im aktuellen. Das Format "RRRR" (ab Oracle V. 7.2 ) behandelt zweistellige Jahreszahlen wie "RR", vierstellige wie "YYYY".
DD-MON-RR altes default-Format verbesert 25-FEB-98 25.2.1998
04-SEP-00 4.9.2000
DD.MM.RR deutsches Format 2-stell. Jahr verbesert 25.02.98 25.2.1998
04.09.00 4.9.2000
DD.MM.RRRR deutsches Format 4-stell. Jahr "relativ" 25.02.1998 25.2.1998
04.09.2000 4.9.2000
zweistelliges Jahr wird vom vierstelligem Jahresformat "RRRR" verstanden 25.02.98 25.2.1998
04.09.00 4.9.2000
Jahre vor 1950 können jetzt nur noch bei vierstelligem Format ("YYYY" oder "RRRR") eingegeben werden. 11.11.1911 11.11.1911

Unzählige weitere Formate und -Kombinationen sind möglich. Hierzu muß auf die originalen SQL-Handbücher und auf gute Sekundärliteratur verwiesen werden.

Ein Beispiel zeigt, was bei einigen Datumsformaten herauskommt, zunächst die Ausgabe

 
SQL> l
  1  select Name,TO_CHAR(Geburtsdatum,'DD-MON-YY') DD_MON_YY,
  2  TO_CHAR(Geburtsdatum,'DD.MM.YY') DD_MM_YY,
  3  TO_CHAR(Geburtsdatum,'DD.MM.YYYY') DD_MM_YYYY,
  4  TO_CHAR(Geburtsdatum,'DD.MM.RRRR') DD_MM_RRRR
  5  from PATIENT
  6  where Geburtsdatum IS NOT NULL
  7*   AND RowNum < 20
SQL> /

NAME                           DD_MON_YY DD_MM_YY DD_MM_YYYY DD_MM_RRRR
------------------------------ --------- -------- ---------- ----------
Testele                        12-MAY-67 12.05.67 12.05.1967 12.05.1967
G2Testcc                       12-JUN-67 12.06.67 12.06.1967 12.06.1967
Schoenholz                     11-NOV-11 11.11.11 11.11.1911 11.11.1911
Testelen                       12-JUN-57 12.06.57 12.06.1957 12.06.1957
Altmann                        01-FEB-58 01.02.58 01.02.1958 01.02.1958
Janssen                        10-OCT-07 10.10.07 10.10.1907 10.10.1907
Schmidt                        11-FEB-96 11.02.96 11.02.1996 11.02.1996
Schmidt                        11-NOV-70 11.11.70 11.11.1970 11.11.1970
Kirschberger                   11-FEB-68 11.02.68 11.02.1968 11.02.1968
Janssen                        04-APR-50 04.04.50 04.04.1950 04.04.1950
Ein 1. Name                    01-JAN-01 01.01.01 01.01.1901 01.01.1901

NAME                           DD_MON_YY DD_MM_YY DD_MM_YYYY DD_MM_RRRR
------------------------------ --------- -------- ---------- ----------
Ein 3. Name                    03-MAR-03 03.03.03 03.03.1903 03.03.1903
Kxxx                           30-AUG-36 30.08.36 30.08.1936 30.08.1936
Wxxxxxx                        02-OCT-57 02.10.57 02.10.1957 02.10.1957
Brxxxyz                        21-OCT-56 21.10.56 21.10.1956 21.10.1956
Dr.Karlmann                    11-NOV-45 11.11.45 11.11.1945 11.11.1945
    .... usw. ......

Wie Sie unschwer erkennen können, unterscheiden sich DD.MM.YYYY und DD.MM.RRRR in der Ausgabe nicht.

Wenn beim Vergleich, bei der Eingabe, Datumswerte einzusetzen sind, muß wiederum entweder das default-Format verwendet werden oder der Datumswert mittels TO_DATE() für Oracle passend verändert. Beispiel - es werden am 11.11.1911 geborene gesucht

 SQL> select Name, TO_CHAR(Geburtsdatum,'DD.MM.YYYY') DD_MM_YYYY
  2  from PATIENT
  3  where Geburtsdatum = '11.11.1911'
  4  /
ERROR:
ORA-01843: not a valid month

no rows selected

Datumswerte werden bei der Eingabe in SQLPLUS wie Zeichenketten in Hochkomma eingeschlossen. In diesem Beispiel sieht man nun, daß Oracle das deutsche Format nicht ohne Weiteres erkennt. Der zweite Versuch erfolgt mit dem default-Format

 
SQL> l
  1  select Name, TO_CHAR(Geburtsdatum,'DD.MM.YYYY') DD_MM_YYYY
  2  from PATIENT
  3* where Geburtsdatum = '11-NOV-11'
SQL> /

no rows selected

SQL>

Gesucht waren die Patienten, welche am 11. November 1911 geboren wurden. Gemäß obiger Format-Tabelle versteht Oracle aber 11-NOV-11 als 11.11.2011 - richtig, daß es nichts gefunden hat. Erst die Anwendung von TO_DATE() liefert das richtige Ergebnis

SQL> l
  1  select Name, TO_CHAR(Geburtsdatum,'DD.MM.YYYY') DD_MM_YYYY
  2  from PATIENT
  3* where Geburtsdatum = TO_DATE('11.11.1911','DD.MM.YYYY')
SQL> /

NAME                           DD_MM_YYYY
------------------------------ ----------
Schoenholz                     11.11.1911
B97test                        11.11.1911
Unsinn                         11.11.1911
Missman                        11.11.1911
Wert                           11.11.1911
Möllemann                      11.11.1911
Mistermann                     11.11.1911
Miesmuschel                    11.11.1911
Mistermann                     11.11.1911
Bender                         11.11.1911
Testfrau                       11.11.1911

NAME                           DD_MM_YYYY
------------------------------ ----------
Testmann                       11.11.1911
Testpatient                    11.11.1911
Pißmal                         11.11.1911
Melana                         11.11.1911

15 rows selected.

Im Vergleich zu den Listen weiter oben ist zu beachten, daß diese gekürzt wurden

Dies ist das richtige Ergebnis.

Ergänzender Hinweis - die Zeitkomponente von Datumsfeldern wurde in den Beispielen etwas stiefmütterlich behandelt. Werden Datumswerte in eine Anwendung wie GTDS über Maskenfelder eingegeben, so ist die dazugehörige Uhrzeit (die ja immer mit gespeichert wird) normalerweise auf 00:00 Uhr gesetzt. In anderen Fällen könnten Datumsfelder mit den Funktionen TRUNC() bzw. ROUND() behandelt werden.

default-Format ändern bei Oracle7

[ zurück]

Oracle7 ermöglicht Ihnen, das Default-Datumsformaat zu ändern. Zwei Ebenen der Einstellung sind zu unterscheiden

1) Parameter für die ganze Datenbank

Eine Reihe von Einstellungen kann über die Parameter-Datei INIT.ORA geschehen, die jeweils beim Start der Datenbank gelesen wird. Mit SQL können diese Werte ganz einfach angezeigt werden :

 
SQL> select * from NLS_DATABASE_PARAMETERS
  2  /

PARAMETER                      VALUE
------------------------------ ------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_DATE_FORMAT                DD-MON-YY
NLS_DATE_LANGUAGE              AMERICAN 
NLS_CHARACTERSET               WE8DEC
NLS_SORT                       BINARY
NLS_CALENDAR                   GREGORIAN
NLS_RDBMS_VERSION              7.3.2.1.0

11 rows selected.

Die beiden Parameter NLS_DATE_FORMAT und NLS_DATE_LANGUAGE bestimmen, wie Datumswerte ausgegeben werden, wenn keine Funktionen wie TO_CHAR() zum Einsatz kommen. NLS_DATE_LANGUAGE legt dabei die Sprache für Tages- und Monatsnamen fest. Obwohl es naheliegt, gleich an dieser Stelle ein günstiges, deutsches Datumsformat festzulegen, ist dieser Weg nicht unbedingt empfehlenswert, da bei der Verwendung einer Vielzahl von Tools und Programmen unerwartete Seiteneffekte auftreten können. Daher ist auch in unserer Testdatenbank der übliche Default belassen.

2) Parameter für die aktuelle Sitzung

Auch für die aktuelle Sitzung, die aktuelle Verbindung mit der Datenbank, können die o.g. Parameter und damit auch das Datumsformat gesetzt werden. Um sie zunächst anzuzeigen, genügt

 
    1* select * from NLS_SESSION_PARAMETERS
SQL> /

PARAMETER                      VALUE
------------------------------ ------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_DATE_FORMAT                DD-MON-YY
NLS_DATE_LANGUAGE              AMERICAN
NLS_SORT                       BINARY
NLS_CALENDAR                   GREGORIAN

9  rows selected.

Mit Alter SESSION SET NLS_DATE_FORMAT = 'Format' kann dann das Datumsformat für die aktuelle Sitzung geändert werden, die Anweisung wird auch unmittelbar wirksam. Einige Beispiele zeigen das Prinzip :

SQL> select name, geburtsdatum from PATIENT
  2  where geburtsdatum is not NULL
  3     AND RowNUM < 4
  4  /

NAME                           GEBURTSDA
------------------------------ ---------
Testele                        12-MAY-67
G2Testcc                       12-JUN-67
Schoenholz                     11-NOV-11

SQL> alter session set NLS_DATE_FORMAT='DD.MM.RRRR';

Session altered.

SQL> select * from NLS_SESSION_PARAMETERS
  2  where PARAMETER LIKE '%DATE%'
  3  /

PARAMETER                      VALUE
------------------------------ ------------------------------
NLS_DATE_FORMAT                DD.MM.RRRR
NLS_DATE_LANGUAGE              AMERICAN

SQL>
  1  select name, geburtsdatum from PATIENT
  2  where geburtsdatum is not NULL
  3*    AND RowNUM < 4
SQL> /

NAME                           GEBURTSDAT
------------------------------ ----------
Testele                        12.05.1967
G2Testcc                       12.06.1967
Schoenholz                     11.11.1911

SQL> select Name, Geburtsdatum
  2  from   PATIENT
  3  where  Geburtsdatum > '1.1.65'
  4  /

NAME                           GEBURTSDAT
------------------------------ ----------
Testele                        12.05.1967
G2Testcc                       12.06.1967
Schmidt                        11.02.1996
Schmidt                        11.11.1970
Kirschberger                   11.02.1968
testiboy                       11.02.1968
Meyer                          07.07.1977
Bdt-Testpatient                17.03.1987
Ali                            16.11.1966
Beckenbauer                    11.02.1968
Zimmer                         01.01.1977

NAME                           GEBURTSDAT
------------------------------ ----------
Klein                          08.08.1988
Testkind                       15.10.1977
Musterli                       15.03.1967
Dick                           10.03.1965

15 rows selected.

In diesem letzten Beispiel sieht man, daß das neue NLS_DATE_FORMAT sofort wirkt und für alle Datumsfelder der aktuellen Sitzung gilt - sowohl bei der Ausgabe (wofür sonst immer einzeln mit TO_CHAR() formatiert werden müßte), als auch bei der Eingabe (wo sonst TO_DATE() nötig wäre, wenn das Datum nicht im default-Format ist). Die WHERE-Klausel where Geburtsdatum > '1.1.65' würde beim default-Format DD-MON-YY nicht angenommen, bei einem Datumsformat mit zweistelligem Jahr würde 65 als 2065 interpretiert und es würden keine Patienten gefunden. Nachdem wir aber mit dem Alter SESSION Befehl das Format DD.MM.RRRR eingestellt haben, wird 65 "relativ" als 1965 verstanden.

Nutzung alter SQL-Skripte

Viele Anwender haben noch ältere SQL-Skripte, die das klassische Datumsformat DD-MON-YY verwenden. Vor dem Jahrtausendwechsel war eine Abfrage auf die Diagnosen in der Art

SQL> select Fk_PatientPat_ID, Tumor_ID, Diagnosetext
     from   TUMOR
     where  Diagnosedatum BETWEEN '01-JAN-95' AND '01-JAN-99' ;
möglich und lieferte die Diagnosen zwischen dem 1.1.1995 und dem 1.1.1999. Im Jahre 2000 war dann überraschenderweise festzustellen, daß derartige Abfragen plötzlich keine Datensätze mehr lieferten ! Dies liegt darin begründet, daß beim default-Format DD-MON-YY das Jahr immer zum aktuellen Jahrhundert ergänzt wird. Nach dem Jahrtausendwechsel würden also von der gleichen Abfrage Diagnosen zwischen dem 1.1.2095 und dem 1.1.2099 gesucht und nicht gefunden ...

Abhilfe ist leicht möglich, wie Sie der Tabelle oben entnehmen können, gibt es die Abwandlung DD-MON-RR für das default-Format. Dann werden Jahre zwischen 51 und 99 als aus dem vergangenen Jahrhundert interpretiert, und andererseits bleibt die Darstellung unverändert, so daß Sie mühsam erstellte SQL-Programme nicht ändern müssen. Nach

 
SQL> alter session set NLS_DATE_FORMAT='DD-MON-RR';
liefert die obige Abfrage auch in 2000 wieder die richtigen Daten.

Datumsformat in Startdateien für SQLPLUS festlegen

Die Einstellung des Datumsformates mittels alter session set NLS_DATE_FORMAT= bleibt wirksam für die aktuelle Sitzung. Wenn Sie SQLPLUS verlassen und neu aufrufen, ist diese Einstellung zurückgesetzt. Sie können jedoch dieses SQL-Statement in eine Datei login.sql im aktuellen Verzeichnis (wo Sie SQLPLUS aufrufen) schreiben bzw. daran anfügen. Dann wird sie jedesmal beim Start von SQLPLUS ausgeführt.

Hinweis für alphanumerische GTDS-Anwender - im typischen GTDS-Verzeichnis unter Unix(®) tusys/gtds-8859 ist nur das Format DD-MON-RR erlaubt, andere können bei den alten Tools zu unliebsamen Überraschungen führen.

[Teil 4]

[Anfang] [voriger Abschnitt] [nächster Abschnitt]

Oracle(®) - Umgebung bestimmen und untersuchen

Beim Erstellen von Abfragen und Berichten werden häufig zunächst weitere Informationen z.B. über die vorhandenen Tabellen, Indizes usw. benötigt. In den meisten Fällen stellt Oracle diese Informationen in Form von Tabellen bzw. Views zur Verfügung, die einfach mit SELECT befragt werden können.

Wer bin ich ?

Manchmal besteht Unklarheit, als welcher Oracle-Benutzer man gerade mit der Datenbank verbunden ist. Klarheit schafft

SQL> select USER from DUAL
  2  /

USER
------------------------------
OPS$DOOF

Ebenso kann die aktuelle Systemzeit der Datenbank bestimmt werden mit

SQL> select TO_CHAR(SysDate,'DD.MM.YYYY HH24:MI:SS')
  2  from DUAL
  3  /

TO_CHAR(SYSDATE,'DD.MM.YYYYHH24:MI:SS')
---------------------------------------------------------------------------
01.09.2000 11:42:30

Spaltenliste für bekannte Objekte

Ist der Name einer Tabelle oder eines View bekannt, können mit dem SQLPLUS-Kommando DESCRIBE (kann zu desc abgekürzt werden) die Spalten und ggf. weitere Informationen ausgelesen werden :

SQL> desc PATIENT
 Name                            Null?    Type
 ------------------------------- -------- ----
 PAT_ID                                   NUMBER(10)
 NAME                                     VARCHAR2(30)
 VORNAME                                  VARCHAR2(30)
 TITEL                                    VARCHAR2(30)
 GEBURTSDATUM                             DATE
 GESCHLECHT                               VARCHAR2(1)
 STERBEDATUM                              DATE
 STERBE_DATUM_EXAKT                       VARCHAR2(1)
 NATIONALITAET                            VARCHAR2(3)
 STRASSE                                  VARCHAR2(30)
 PLZ                                      VARCHAR2(6)
 LANDESKENNUNG                            VARCHAR2(3)
 ORT                                      VARCHAR2(30)
 ... usw. ...

Auflisten der eigenen Objekte

Mit dem einfachen

SQL> select * from CAT
  2  /

TABLE_NAME                     TABLE_TYPE
------------------------------ -----------
ABTEILUNG                      TABLE
ADRESSEN                       TABLE
CHIRURGIE                      SYNONYM
DOOFRUF                        TABLE
GTDS_ZENTRUM                   TABLE
HNO                            SYNONYM
LONGTEST                       TABLE
PLAN_TABLE                     TABLE
TEST                           TABLE
TESTE                          VIEW
TEXTDATEIEN                    TABLE

11 rows selected.

erhalten Sie eine Auflistung der eigenen Tabellen. CAT ist dabei ein Kürzel (Synonym) für USER_CATALOG. Die Spalten der aufgelisteten Objekte erhalten Sie dann mittels DESC (s.o.), den Inhalt mittels SELECT-Anweisungen.

Auflisten aller zugreifbaren Objekte

Neben den eigenen Objekten können noch weitere existieren, auf die man Zugriff hat. Dazu gehören neben den typischen Informationstabellen des Systems (wie USER_CATALOG) auch Tabellen anderer Nutzer, die dafür Rechte erteilt haben. GTDS macht davon ausgedehnten Gebrauch - die Tabellen gehören OPS$TUMSYS, der jedoch den Benutzerinnen des GTDS passende Rechte auf diese Tabellen erteilt (GRANT). Durch eine Abfrage auf ALL_CATALOG sehen Sie die Ihnen zugänglichen Objekte :

SQL> select * from ALL_CATALOG order by Owner,Table_Name
   2   /


OWNER                          TABLE_NAME                     TABLE_TYPE
------------------------------ ------------------------------ -----------
OPS$DOOF                       TEST                           TABLE
OPS$DOOF                       TESTE                          VIEW
OPS$DOOF                       TEXTDATEIEN                    TABLE
OPS$TUMSYS                     AA_DIAGNOSESICHERUNG           TABLE
OPS$TUMSYS                     ABRECHNUNGSSTELLE              TABLE
OPS$TUMSYS                     ABSCHLUSS                      TABLE
OPS$TUMSYS                     ABSCHLUSS_PROTOKOLL            TABLE
OPS$TUMSYS                     ABSCHLUSS_VIEW                 VIEW
OPS$TUMSYS                     ABTEILUNG                      TABLE
OPS$TUMSYS                     ABTEILUNGS_KUERZEL             TABLE
OPS$TUMSYS                     ABTEILUNG_DEFAULTS             TABLE
  ..................

Hier kann nur ein Ausschnitt wiedergegeben werden, die komplette Ausgabe umfaßt nahezu 2000 Zeilen.

Weitere Informations-Tabellen

zahlreiche weitere Informationen über die Datenbank und ihre Objekte werden von Oracle in Form von Tabellen zur Verfügung gestellt, wobei die Möglichkeiten je nach Benutzer-Rechten variieren. Eine Übersicht über alle solche Tabellen erhalten Sie mit

SQL> l
  1* select * from dictionary
SQL> /


TABLE_NAME       COMMENTS
---------------- --------------------------------------------------------------
ALL_ARGUMENTS    Arguments in object accessible to the user
ALL_CATALOG      All tables, views, synonyms, sequences accessible to the user
ALL_CLUSTERS     Description of clusters accessible to the user
ALL_CLUSTER_HASH Hash functions for all accessible clusters
_EXPRESSIONS

ALL_COL_COMMENTS Comments on columns of accessible tables and views
ALL_COL_PRIVS    Grants on columns for which the user is the grantor, grantee,
                 owner,
                 or an enabled role or PUBLIC is the grantee

 ................. usw. ..............

Jene Tabellen und Views, deren Namen mit USER_ beginnen, beziehen sich dabei immer auf die eigenen Objekte, jene deren Namen mit ALL_ anfangen auf alle zugreifbaren.

Für GTDS-Anwender stehen eine Reihe von fertigen Skripten für bestimmte Aufgaben (etwa alle Indizes zu einer Tabelle auflisten) zur Verfügung. Beim alnum GTDS befinden sie sich im Verzeichnis sqlutil/ , grafischen Anwendern werden sie auf Wunsch separat zur Verfügung gestellt.

Tabelleninformationen im GTDS

In der Dokumentation zum grafischen GTDS befindet sich (im Unterverzeichnis Hilfe vom grafischen GTDS -Verzeichnis) die Datei Tabellen.htm mit einer Auflistung der Tabellen und ihrer Spalten im GTDS. Sowohl im alnum als auch im grafischen GTDS können Tabelleninformationen über Bildschirm-Masken abgerufen werden.

[Teil 5]

[Anfang] [voriger Abschnitt]

Kurze Hinweise zum Gebrauch von SQL*Plus


Das Werkzeug SQL*Plus unterstützt die Ausführung, Eingabe und Formatierung von SQL-Statements unter Oracle. Einige Besonderheiten sollen im folgenden gezeigt werden :

Aufruf von SQL*Plus :

SQL*Plus wird mit dem Befehl
sqlplus Benutzer/Passwort

aufgerufen. Hat man einen OPS$ -Account unter Oracle, so kann der Aufruf in der Form

sqlplus / 

geschehen ( also z.B. als kurs2 unter Unix eingeloggt, Oracle-Benutzername OPS$KURS2 ).

Werden Benutzername und/oder Paßwort nicht angegeben, fragt SQL*Plus sie ab.

Hier im Kurs können Sie evtl. SQL*Plus einfach aus dem Menü bzw. aus dem GTDS heraus aufrufen .

Bei Oracle(®)-Installationen unter Windows95/98/NT(®) steht gewöhnlich ein Icon auf dem Desktop (großes gelbes Pluszeichen über Plattenstapel) bzw. ein Punkt im Startmenü unter den "Oracle Products for Windows" o.ä. zur Verfügung.
Möchten Sie jedoch SQLPLUS von der Befehlszeile aus starten, so erhalten Sie mittels plus33 bzw. plus80 (Oracle8) die rein zeilenorientierte Version, mittels plus33w bzw. plus80w (Oracle8) die Windows-Version.

Beide Versionen fragen zunächst nach Oracle-Benutzernamen, Paßwort und dem Datenbank-Namen. Mit letzterem ist der Name eines Database Alias (SQL*Net Alias) gemeint, welcher einmal zuvor, vorteilhafterweise mittels SQL*Net Easy Config, definiert wurde.


Verlassen von SQL*Plus

mit dem Kommando exit oder quit bzw. Eingabe von Control-D am Anfang einer Zeile wird SQL*Plus verlassen.

Eingabe von SQL-Statements :

Am Eingabeprompt SQL> (oder ähnlich) gibt man seine SQL-Statements ein. Sind sie für eine Zeile zu lang, gibt man einfach <Return> ein und schreibt in der nächsten Zeile weiter. Mit ; (Semikolon) werden SQL-Statements abgeschlossen und zur Ausführung übergeben. Stattdessen kann man auch / (Slash) am Anfang einer Zeile eingeben. Gibt man nur / am Anfang einer Zeile ein, wiederholt SQL*Plus das letzte eingegebene SQL-Statement ohne weitere Eingabe, da er SQL-Statements in einem Puffer speichert. Mit Control-C kann man die aktuelle Aktion abbrechen.

SQL*Plus - Kommandos

Im folgenden werden Variable kursiv bezeichnet, dafür müssen Sie dann einen echten Wert einsetzen, z.B. einen echten Dateinamen für Datei oder eine Zahl für NNN.

Eine Reihe von nützlichen Kommando, die von SQL*Plus außerhalb SQL ausgeführt werden, stehen zur Verfügung ( GROß- oder klein schreibung ist wie auch bei SQL selbst beliebig ). Diese Kommandos müssen nicht mit Semikolon abgeschlossen werden. Zur Darstellung s. Konventionen im SQL-Skript. Teile in [] sind optional (meistens kann das Kommando abgekürzt werden, z.B. desc statt describe). SQL*Plus-Kommandos werden nicht in einem Puffer gespeichert, d.h. sie müssen bei der interaktiven Arbeit immer wieder eingegeben werden. Jedoch können sie sich in einer Kommandodatei (s.u.) befinden.


l[ist]
Listet das aktuell noch gespeicherte Statement auf. Dieses SQL-Statement könnte durch einfach Eingabe eines Schrägstriches ( / ) erneut ausgeführt werden.
ed
Holt das aktuelle SQL-Statement in den Texteditor. Dieser Editor kann mit dem Befehl define _editor = <Kommando> , z.B. define _editor = vi festgelegt werden. Letzteres Kommando können Sie direkt eingeben, oder aber in der Datei login.sql im aktuellen Verzeichnis speichern, die von SQL*Plus bei jedem Aufruf in diesem Verzeichnis gelesen wird.

Zur Kursumgebung siehe evtl. den Anhang : Statements editieren unter SQL*Plus. Im Kurs gibt es aus praktischen Gründen eine gemeinsame login.sql -Datei.


ed Datei
Holt die Datei Datei.sql in den Texteditor.

start Datei
@ Datei
Führt Datei bzw. Datei.sql aus (wenn keine Endung angegeben). Diese Datei wird als SQL*Plus-Kommandodatei behandelt. Auch der Aufruf von SQL*Plus aus der Kommandozeile kann mit einer Kommandodatei geschehen in der Form sqlplus user/passwort @ Datei . Soll SQL*Plus danach unmittelbar wieder verlassen werden, muß die Kommandodatei als letzten Befehl EXIT enthalten.

save Datei
speichert das aktuelle SQL-Statement (nur das) in Datei. Hat der angegebene Name keine Endung, wird .sql angehängt.
get Datei
lädt Datei nach SQL*Plus. Ist nur sinnvoll, wenn Datei nur ein SQL-Statement enthält und keine SQL*Plus-Befehle wie COL oder BREAK. Diese könnte dann sofort mit / (Schrägstrich) und Return ausgeführt werden.
ho[st]
Führt das angegebene Betriebssystemkommando aus,z.B. unter Unix host ls oder unter MSDOS host DIR . Statt host kann unter Unix, wie auch in manchen anderen Programmen, ! (Ausrufezeichen) verwendet werden. Fehlt das Argument, wird einfach der Kommandointerpreter des Betriebssystems aufgerufen ( also gelangt man unter Unix in eine Shell und unter MSDOS in COMMAND.COM ). Er kann mit exit wieder verlassen werden.
desc[ribe] Tabelle

gibt eine Übersicht über die Spalten, Datentypen usw. von Tabelle
spo[ol] Datei
schreibt alles, was SQL*Plus ab sofort ausgibt, in datei.lst . Mit SPOOL OFF wird diese Ausgabe beendet. Beispiel:
SPOOL liste
schreibt alle folgenden Ausgaben in die Datei liste.lst
SPOOL OFF
beendet diese Ausgabe und schließt die Datei.

help

fordert Hilfe an, z.B. help select . Dazu müssen bei der Installation die SQL*Plus - Hilfetabellen geladen worden sein (ist natürlich hier der Fall).
set pagesize nnn

legt die Seitengröße (in Zeilen pro Seite ) für SQL*Plus fest
set linesize nnn

legt die Zeilenlänge für SQL*Plus fest, damit auch, ab wann Zeilen umgebrochen werden. Erfolgt die Ausgabe in eine Datei (SPOOL, s.o.), werden alle Zeilen bis zu dieser Länge mit Leerzeichen aufgefüllt !
set spa[ce] nnn

legt die Abstände (Zahl der Leerzeichen) zwischen den einzelnen Spalten fest, wenn SQL*Plus die Ergebnisse einer SQL-Abfrage darstellt. Voreinstellung ist 1 (eine Leerstelle zwischen den Spalten). Nach set space 0 werden die Spalten einfach ohne Zwischenraum hintereinandergeschrieben (manchmal nützlich für den Datentransfer zu anderen Systemen). für SQL*Plus fest
set pause on

Ist pause eingeschaltet, wartet SQL*Plus nach dem Start eines Select-Statements zunächst auf die Eingabe <Return>, um dann nach jeweils <pagesize> Zeilen wieder zu pausieren und auf <Return> zu warten (oder Control-C zum Abbruch). Dieser Modus kann mit set pause off wieder ausgeschaltet werden.

Spaltenüberschriften und Formatierung

SQL*Plus stellt Ergebnisse von SQL-Abfragen in einem Standardformat dar, mit Spaltenüberschriften. Eine Fülle von Kommandos und Direktiven erlaubt dies zu modifizieren und macht auf diese Weise SQL*Plus zu einem einfachen Reportgenerator. An dieser Stelle können nur einige Möglichkeiten angedeutet werden:

set heading on bzw. set heading off
- schaltet die Spaltenüberschriften ein oder aus.
col[umn] Spalte head Überschrift

Gibt die angegebene Überschrift über der entsprechenden Spalte aus dem Select-Statement aus. Besteht sie nicht aus einem Wort, muß sie in Hochkomma eingeschlossen sein '...' . In diesem Falle kann man auch mit | einen Zeilenvorschub in der Überschrift unterbringen.
col[umn] Spalte for[mat] Format

erlaubt Spalten für die Ausgabe von Select zu formatieren, insbesondere ihre Länge zu bestimmen (wichtig bei VARCHAR-Spalten, deren Länge vom maximal möglichen Inhalt bestimmt wird).
Format wird bei CHAR und VARCHAR - Spalten in der Form aNNN angegeben, NNN steht dabei für die Länge als ganze Zahl, z.B. col name for a20 .Der Name wird dann bei mehr als 20 Zeichen Länge umgebrochen. Dieses Verhalten kann jedoch in verschiedenster Weise modifiziert werden.
Für numerische Spalten gibt es verschiedene Formate. Am wichtigsten sind die Formate 999990 (Anzahl der 9 und 0 bestimmt die Anzahl der Ziffern) und 9.99999EEEE (wissenschaftliche Notation, im Format müssen genau vier E stehen.). Beispiele: col pat_id for 9990 für vierstellige Anzeige der Pat_id oder col gewicht for 999.0 für Anzeige des Gewichtes mit einer Nachkommastelle.
Datumsfelder formatiert man zweckmäßig mit den Fähigkeiten von TO_CHAR() für Datumsfelder (s. SQL-Skript und SQL-Referenzhandbuch).

Erweiterte Möglichkeiten von SQL*Plus : Die Fähigkeiten dieses Werkzeuges gehen weit über den Rahmen dieser Darstellung hinaus. So können zum Beispiel mit den Kommandos BREAK und COMPUTE Gruppenwechsel bearbeitet, Zwischen- und Endsummen gebildet werden usw.. Ferner kann von SQL*Plus aus PL/SQL, die Datenbank-Programmiersprache von Oracle, eingegeben und ausgeführt werden. Eine weitere wichtige Möglichkeit ist die Verwendung von SQL*Plus als Codegenerator für sich selbst: durch sinnreiche SQL-Statements können wiederum SQL-Statements und Anweisungen für SQL*Plus erzeugt werden. Leitet man diese Ausgaben mit spool in eine Datei, kann diese evtl. anschließend wiederum mit start ausgeführt werden. Diese Technik kann z.B. Verwendung finden, wenn ein Benutzer einem anderen Rechte für alle seine Tabellen mit GRANT verleihen will.




Einfacher Beispiel-Report mit SQL*Plus



Dieser Report verwendet die elementaren Funktionen von SQL*Plus. Das (etwas an den Haaren herbeigezogene) Ziel ist es, eine Auflistung der Patienten, pro Krankenkasse sortiert, formatiert zu produzieren. Gleichzeitig soll das durchschnittliche Alter der Patienten ermittelt werden.

Einen solchen Report erstellt man mit einem Editor und speichert ihn in eine Datei, z.B. kassenpatient.sql. Danach kann er aus SQL*Plus mit START kassenpatient aufgerufen werden. Vorher kann man in interaktiver Arbeit mit SQL*Plus Teile schrittweise eingeben und testen. Aus SQL*Plus kann jederzeit der Editor mittels ed kassenpatient aufgerufen und anschließend die verbeserte Reportdefinition wieder gestartet werden.

Der Beispielreport benutzt Tabellen, wie es sie tatsächlich im GTDS gibt.




rem Kopf- und Fußtitel für die Seiten
ttitle 'Patientenliste|sortiert nach Krankenkassen'
btitle '(Auszug aus dem aktuellen Datenbestand des Registers)'

rem Spaltenformatierung
column Leistungstraeger format a20 word_wrapped
column name format a20 word_wrapped
column vorname format a15 truncated
rem to_char gibt sonst eine Länge von ca. 100
column geboren format a10 truncated heading 'Geb. am'
column Lebensalter format 90 heading 'Alter|(Jahre)'

rem Gruppenwechsel und Altersberechnung
rem zu break muß immer ein order by auf die gleiche Spalte passen
break on Leistungstraeger skip 2
compute avg of Lebensalter on Leistungstraeger

rem Seitendimensionen, newpage 0 sendet Formfeed zum Seitenwechsel
set linesize 79
set pagesize 60
set newpage 0
spool kassenliste
select Leistungstraeger,Name,Vorname,
	TO_CHAR(Geburtsdatum,'DD.MM.YYYY') Geboren,
       (NVL(Sterbedatum,SysDate) - Geburtsdatum) / 365 Lebensalter
from LEISTUNGSTRAEGER, PATIENT
where Institutionskennze=Fk_Leistungstraeins
order by Leistungstraeger,Name,Vorname
/
spool off


ANHANG : Statements editieren unter SQL*Plus



Die Kommandozeilen-Eingabe unter SQL*Plus ist leider etwas altmodisch und simpel. Bei der Eingabe am Prompt SQL> können Sie die Cursor-Tasten nicht benutzen, von Pos1, Ende, Bild usw. mal ganz zu schweigen. Hat man sich vertippt, muß man normalerweise mit Backspace bis zum Fehler zurück löschen und von da aus neu schreiben. Zurückholen voriger Zeilen mit SQL*Plus -Kommandos ist nicht möglich. Ebensowenig gibt es einen Komplettierungsmechanismus, wie Sie ihn vielleicht von der Befehlszeile von Kermit kennen. Der Eingabekomfort entspricht damit alten Shell-Befehlszeilen (!).

Nur SQL- (nicht SQL*Plus-) Befehle werden in einem Puffer gespeichert. Ein SQL-Befehl (also Select, Insert, Update usw.) kann mit / allein auf einer Zeile wiederholt werden. Innerhalb von SQL*Plus steht nur ein ganz begrenzter Editor nur für SQL-Statements zur Verfügung. Im Grunde genommen sind nur wenige Befehle nützlich :

l[ist]
listet das aktuelle SQL-Statement mit Zeilennummern auf.
NNN
macht die Zeile mit der angegebenen Nummer zur aktuellen Zeile.
c/Text/Ersatz

ersetzt in der aktuellen Zeile Text\f1 durch \f2Ersatz\f1 . In \f2Text wirkt ... wie ein * in der Shell, d.h. steht für beliebigen Text.
I[nput]

Fügt Zeilen hinter der aktuellen hinzu. Siehe Beispiele im SQL*Plus User's Guide and Reference, Kapitel 6 S. 45.
A[ppend]

fügt Text an die aktuelle Zeile an (nach Append zwei oder mehr Leerzeichen eingeben, wenn Text vom vorhandenen Teil der Zeile durch Leerstellen getrennt sein soll). Siehe Beispiele im SQL*Plus User's Guide and Reference, Kapitel 6 S. 8.

Will man komplexere Änderungen vornehmen, SQL*Plus-Statements oder ganze Reports editieren, sollte man immer zum Editor greifen. Einzelne, gerade im aktuellen Zugriff befindliche SQL -Statements kann man einfach mit ed am SQL*Plus-Prompt in den Editor holen, wobei das Statement dann in einem Puffer mit dem Namen afiedt.buf editiert wird. Für komplexere Dinge ist stets eine eigene Datei erforderlich, die zur Ausführung mit SQL*Plus die Endung .sql haben sollte. Der Editor wird mit einer solchen Kommandodatei, z.B. dem Beispielreport (s.o.) aus SQL*Plus einfach mit ed Datei aufgerufen (s.o). Selbstverständlich kann man eine solche Datei auch ganz außerhalb von SQL*Plus erstellen.

Als Editor wird im Kurs vsl. joe benutzt, ein frei verfügbares Programm, welches im Prinzip wie das wohlbekannte Textprogramm WordStar funktioniert. Mit Strg-K H können Sie ein Hilfefenster anschalten, mit Strg-C den Editor verlassen.

Unter Windows können SQL-Statements mit dem Notepad editiert werden, und viele OPtionen von SQL*Plus werden in einer interaktiven, grafischen Oberfläche gesetzt.

[Anfang] [voriger Abschnitt]

ANHANG :
Beispiel Benutzereinrichtung

So wird z.B. OPS$TUMSYS im GTDS eingerichtet. Das Skript übernimmt drei Argumente für

  1. den neuen Oracle-Benutzernamen
  2. das anfängliche Paßwort
  3. den TABLESPACE (Teilbereich der Datenbank), wo der neue Benutzer zunächst seine Objekte anlegen soll.


PROMPT "USER_ACC <USER> <PASSWD> <TABLESPACE>"
select TABLESPACE_NAME from sys.dba_tablespaces
/
CREATE USER  &1 IDENTIFIED BY &2
/
GRANT CREATE SESSION TO &1
/
GRANT CREATE VIEW TO &1
/
ALTER USER &1 DEFAULT TABLESPACE &3 TEMPORARY TABLESPACE &3
/
ALTER USER &1 QUOTA UNLIMITED ON &3
/
GRANT CREATE CLUSTER TO &1
/
GRANT CREATE ANY INDEX TO &1
/
GRANT CREATE PROCEDURE TO &1
/
GRANT ALTER SESSION TO &1
/
GRANT CREATE SEQUENCE TO &1
/
GRANT CREATE SYNONYM TO &1
/
GRANT CREATE TABLE TO &1
/
GRANT CREATE TRIGGER TO &1
/

[Anfang]
[zurück]