Anfang des Inhaltsbereichs

Selektion definieren Dokument im Navigationsbaum lokalisieren

Die SELECT-Klausel definiert die Struktur der Ergebnismenge (Selektion), für die von der Datenbank zu lesenden Daten.

Diese Grafik wird im zugehörigen Text erklärt

Die Selektion kann eine einzelne Zeile also flach sein, oder aus mehreren Zeilen bestehen, also tabellenartig sein. Doppelt vorkommende Zeilen können ausgeschlossen werden. Die SELECT-Klausel bestimmt weiterhin die zu lesenden Spalten und definiert deren Namen. Dabei können die Namen aus der Datenbanktabelle durch alternative Spaltennamen ersetzt werden Auf einzelne Spalten können Aggregatfunktionen angewendet werden.

Die SELECT-Klausel läßt sich in zwei Teile für Zeilen und Spalten unterteilen:

SELECT <lines> <cols>...

In <lines> wird angegeben ob eine einzelne oder mehrere Zeilen gelesen werden. In <cols> wird die Spaltenauswahl definiert.

Einzelne Zeilen lesen

Um eine einzelne Zeile zu lesen schreibt man für <lines>:

SELECT SINGLE <cols>... WHERE...

Um die zu lesende Zeile eindeutig zu bestimmen müssen alle Felder des Primärschlüssels der Datenbanktabelle in der WHERE-Klausel eingegrenzt werden. Falls die WHERE-Klausel nicht eindeutig ist, wird bei der Syntax-Prüfung eine Warnung ausgegeben und beim Datenbankzugriff die erste gefundene Zeile gelesen.

Das Ergebnis der Selektion ist je nach der Spaltenangabe in <cols> ein elementares Feld oder eine flache Struktur. Der Zielbereich der INTO-Klausel muß entsprechend konvertierbar sein.

Wird eine Zeile mit dem angegebenen Schlüssel gefunden, wird SY-SUBRC auf 0, ansonsten auf 4 gesetzt.

Mehrere Zeilen lesen

Um mehrere Zeilen zu lesen, schreibt man für <lines>:

SELECT [DISTINCT] <cols>... WHERE...

Ohne Angabe von DISTINCT (<lines> ist also leer), werden alle Zeilen in Abhängigkeit von der WHERE-Klausel gelesen. Bei der Angabe von DISTINCT werden doppelt vorkommende Zeilen ausgeschlossen.

Das Ergebnis der Selektion ist eine Tabelle. Der Zielbereich der INTO-Klausel kann eine interne Tabelle mit einem zu <cols> passenden Zeilentyp sein. Falls der Zielbereich keine interne Tabelle sondern eine flache Struktur mit passendem Datentyp ist, muß nach der SELECT-Anweisung eine ENDSELECT-Anweisung folgen:

SELECT [DISTINCT] <cols>... WHERE...
...
ENDSELECT.

Die gelesenen Zeilen werden eine nach der anderen in einer Schleife in den Zielbereich der INTO-Klausel gestellt. Der Zielbereich kann innerhalb der Schleife ausgewertet werden.

Wird mindestens eine Zeile gelesen, wird SY-SUBRC nach der Bearbeitung der Anweisung bzw. der gesamten Schleife auf 0 gesetzt, ansonsten auf 4. Die Anzahl der gelesenen Zeilen wird dem Systemfeld SY-DBCNT zugewiesen, wobei SY-DBCNT auch schon innerhalb jedes Schleifendurchlaufs die Anzahl der bisher an den Zielbereich übergebenen Zeilen enthält.

Es ist zwar möglich, SELECT-Schleifen zu schachteln, dies sollte aus Performance-Gründen aber möglichst nicht geschehen. Falls mehrere Datenbanktabellen bedingt voneinander gelesen werden sollen, können Joins in der FROM-Klausel und Subqueries in der WHERE-Klausel verwendet werden.

Alle Spalten lesen

Um alle Spalten zu lesen schreibt man für <cols>:

SELECT <lines> * ...

Es werden alle Spalten der angegebenen Zeilen gelesen. Der Datentyp der selektierten Zeilen ist eine Struktur die genau dem Datentyp der Datenbanktabelle im ABAP Dictionary entspricht. Der Zielbereich der INTO-Klausel sollte zu diesem Datentyp kompatibel, zumindest aber konvertibel sein. In den übrigen Klauseln können die Spalten nur unter ihrem Namen aus der Datenbanktabelle angesprochen werden.

Das Lesen einzelner Spalten kann erheblich performanter sein, als alle Spalten einer Datenbanktabelle zu lesen. Es sollten deshalb immer nur die Spalten gelesen werden, die auch im Programm benötigt werden.

Einzelne Spalten lesen

Um einzelne Spalten zu lesen schreibt man für <cols>:

SELECT <lines> <s 1> [AS <a 1>] <s 2> [AS <a 2>] ...

Hierbei bezeichnen die <s i > einzelne Spalten. Zur Bezeichnung einzelner Spalten gibt es verschiedene Feldbezeichner, die je nach den Angaben in der FROM-Klausel gewählt werden müssen:

In der SELECT-Klausel kann durch den Zusatz AS für jede Spalte <s i > ein alternativer Spaltenname <a i > definiert werden. Der alternative Spaltenname wird in der INTO-Klausel und in der ORDER-BY-Klausel statt dem richtigen Spaltennamen verwendet. Beispielsweise kann so erreicht werden, daß bei der Variante INTO CORRESPONDING FIELDS der INTO-Klausel der Inhalt einer Spalte <s i > in eine Komponente <a i > einer Struktur geschrieben wird.

Der Datentyp einzelner Spalten ist der Dictionary Typ der entsprechenden Domäne im ABAP Dictionary. Die Datentypen der Zielfelder in der INTO-Klausel sollten so gewählt werden, daß die Dictionary Typen problemlos konvertiert werden können. Eine Tabelle der Dictionary Typen und ihrer ABAP-Entsprechungen findet sich unter Datentypen im ABAP Dictionary.

Aggregate einzelner Spalten lesen

Um Aggregate, also zusammengefaßte Daten, einzelner Spalten zu lesen, schreibt man für <cols> folgende Aggregatausdrücke:

SELECT <lines> <agg>( [DISTINCT] <s 1>) [AS <a 1>]
               <agg>( [DISTINCT] <s2>) [AS <a 2>]
...

Hierbei sind die <s i > die gleichen Feldbezeichner wie oben. Der Ausdruck <agg> steht für eine der folgenden Aggregatfunktionen:

Mit DISTINCT können doppelt vorkommende Werte aus der Berechnung ausgeschlossen werden. Die Leerzeichen zwischen den Klammern und den Argumenten können in den Aggregatausdrücken nicht weggelassen werden. Die arithmetischen Funktionen AVG und SUM können nur mit numerischen Feldern arbeiten.

Der Datentyp von Aggregatausdrücken mit den Funktionen MAX, MIN oder SUM ist der Dictionary Typ der entsprechenden Spalte. Aggregatausdrücke mit der Funktion AVG haben den Dictionary Typ FLTP und solche mit COUNT haben den Dictionary Typ INT4. Das Zielfeld sollte den entsprechenden Typ haben. Bei Durchschnittsberechnungen empfiehlt sich der ABAP-Typ F. Es ist zu beachten, daß Rundungen auf dem Datenbanksystem eventuell anders berechnet werden, als in ABAP. Bei Summenbildung muß der Wertebereich genügend groß sein.

Anders als ABAP erkennen Datenbanksysteme Null-Werte in Datenbankfeldern. Ein Null-Wert bedeutet, daß das Feld keinen Inhalt hat und es geht in die Berechnung nicht ein. Nur wenn alle Zeilen enthalten in dem Feld den Null-Wert enthalten, dann ist auch das Ergebnis der Null-Wert. In ABAP wird ein Null-Wert je nach Datentyp als die Zahl Null interpretiert.

Mit dem Zusatz AS kann für jeden Aggregatausdruck ein alternativer Spaltenname <a i > definiert werden. Der alternative Spaltenname wird in der INTO-Klausel und in der ORDER-BY-Klausel statt dem richtigen Spaltennamen verwendet. Nur so kann erreicht werden, daß in der ORDER-BY-Klausel nach einem Aggregatausdruck sortiert wird.

Falls die Liste der SELECT-Klausel außer Aggregatausdrücken einen oder mehrere Feldbezeichner enthält, dann müssen diese Feldbezeichner auch in der GROUP-BY-Klausel aufgeführt werden. Die Aggregatfunktionen wirken dann nicht auf alle selektierten Zeilen auf einmal, sondern einzeln für jede Zeilengruppe.

Dynamische Spaltenangaben

Die Angabe <cols> kann auch dynamisch gemacht werden:

SELECT <lines> (<itab>) ...

In den Klammern muß der Name einer internen Tabelle <itab> stehen, die entweder leer ist oder die Angaben <s 1 > <s 2 >... zum Lesen einzelner Spalten bzw. entsprechende Aggregatausdrücke enthält. Der Zeilentyp von <itab> muß ein elementares Feld vom Typs C mit einer maximalen Länge von 72 sein. Ist die interne Tabelle leer, bezeichnet sie alle Spalten.

Beispiel

Lesen bestimmter Spalten einer einzigen Zeile.

REPORT demo_select_single.

DATA wa TYPE spfli.

SELECT  SINGLE carrid connid cityfrom cityto
  INTO  CORRESPONDING FIELDS OF wa
  FROM  spfli
  WHERE carrid EQ 'LH' AND connid EQ '0400'.

IF sy-subrc EQ 0.
  WRITE: / wa-carrid, wa-connid, wa-cityfrom, wa-cityto.
ENDIF.

Die Listenausgabe ist:

Diese Grafik wird im zugehörigen Text erklärt

Durch die Angabe SINGLES in der SELECT-Klausel liest die SELECT-Anweisung eine einzige Zeile der Datenbanktabelle SPFLI, in der die Primärschlüsselfelder CARRID und CONNID entsprechend der WHERE-Klausel gefüllt sind. Die in der SELECT-Klausel angegebenen Spalten werden in die gleichnamigen Komponenten der Struktur WA geschrieben.

Beispiel

Lesen bestimmter Spalten mehrerer Zeilen.

REPORT demo_select_some_columns.

DATA: itab TYPE STANDARD TABLE OF spfli,
      wa LIKE LINE OF itab.

SELECT   carrid connid cityfrom cityto
  INTO   CORRESPONDING FIELDS OF TABLE itab
  FROM   spfli
  WHERE  carrid EQ 'LH'.

IF sy-subrc EQ 0.
  LOOP AT itab INTO wa.
    WRITE: / wa-carrid, wa-connid, wa-cityfrom, wa-cityto.
  ENDLOOP.
ENDIF.

Die Listenausgabe ist:

Diese Grafik wird im zugehörigen Text erklärt

Da keine Angabe zu den Zeilen in der SELECT-Klausel gemacht werden, liest die SELECT-Anweisung alle Zeilen der Datenbanktabelle SPFLI, welche die Bedingung in der WHERE-Klausel erfüllen. Die in der SELECT-Klausel angegebenen Spalten werden in die gleichnamigen Komponenten der Tabelle ITAB geschrieben.

Beispiel

Lesen aller Spalten mehrerer Zeilen.

REPORT demo_select_all_columns.

DATA wa TYPE spfli.

SELECT  *
  INTO  CORRESPONDING FIELDS OF wa
  FROM  spfli
  WHERE carrid EQ 'LH'.

  WRITE: / sy-dbcnt,
           wa-carrid, wa-connid, wa-cityfrom, wa-cityto.

ENDSELECT.

Die Listenausgabe ist:

Diese Grafik wird im zugehörigen Text erklärt

Da keine Angabe zu den Zeilen in der SELECT-Klausel gemacht werden, liest die SELECT-Anweisung alle Zeilen der Datenbanktabelle SPFLI, welche die Bedingung in der WHERE-Klausel erfüllen. Alle Spalten der Tabelle werden in die gleichnamigen Komponenten einer flachen Struktur WA geschrieben. Deshalb muß eine mit ENDSELECT abgeschlossene SELECT-Schleife programmiert werden.

Beispiel

Aggregatfunktionen.

Die Datenbanktabelle TEST bestehe aus zwei Spalten und 10 Zeilen:

COL_1

COL_2

1

3

2

1

3

5

4

7

5

2

6

3

7

1

8

9

9

4

10

3

Der folgende Programmabschnitt demonstriert die Aggregatfunktionen:

DATA RESULT TYPE P DECIMALS 2.

SELECT   <agg>( [DISTINCT] COL_2)
  INTO   RESULT
  FROM   TEST.

WRITE RESULT.

Folgende Tabelle zeigt die Ergebnisse dieser Programmzeilen, die sich aus verschiedenen Kombinationen von Aggregatausdrücken <agg> mit dem Zusatz DISTINCT ergeben.

Aggregatausdruck

DISTINCT

Ergebnis

MAX

nein

9.00

MAX

ja

9.00

MIN

nein

1.00

MIN

ja

1.00

AVG

nein

3.80

AVG

ja

4.43

SUM

nein

38.00

SUM

ja

31.00

COUNT

ja

7.00

COUNT( * )

---

10.00

Beispiel

Dynamische Spaltenangaben

REPORT demo_select_dynamic_columns.

DATA: itab TYPE STANDARD TABLE OF spfli,
      wa LIKE LINE OF itab.

DATA: line(72) TYPE c,
      list LIKE TABLE OF line(72).

line = ' CITYFROM CITYTO '.
APPEND line TO list.

SELECT DISTINCT (list)
  INTO CORRESPONDING FIELDS OF TABLE itab
  FROM spfli.

IF sy-subrc EQ 0.
  LOOP AT itab INTO wa.
    WRITE: / wa-cityfrom, wa-cityto.
  ENDLOOP.
ENDIF.

Die Listenausgabe ist:

Diese Grafik wird im zugehörigen Text erklärt

In der internen Tabelle ITAB sind die aus der Datenbanktabelle SPFLI zu lesenden Spalten angegeben. Durch die Angabe DISTINCT in der SELECT-Klausel liest die SELECT-Anweisung alle Zeilen die in diesen beiden Spalten einen unterschiedlichen Inhalts haben. Es ergibt sich eine Liste der möglichen Flugstrecken.

 

 

Ende des Inhaltsbereichs