Erste Schritte
Grundlegende Methoden und Konzepte anwenden
Mit lokalen Klassen arbeiten
Daten aus der Datenbank lesen
Mit strukturierten Datenobjekten arbeiten
Mit komplexen internen Tabellen arbeiten
Datenbankänderungen mit Business Objects implementieren
Das ABAP-RESTful-Anwendungsprogrammiermodell beschreiben

Mit strukturierten Datenobjekten arbeiten

Objectives

After completing this lesson, you will be able to:
  • Arbeiten Sie mit strukturierten Datenobjekten.
  • Verwenden Sie strukturierte Datenobjekte in ABAP SQL.

Strukturierte Datenobjekte

Um auf eine Komponente einer Struktur zuzugreifen, müssen Sie ein Minuszeichen (-) zwischen den Strukturnamen und den Komponentennamen setzen.

Notiz

Vor oder nach dem Komponentenselektor sind keine Leerzeichen erlaubt.

Wenn Sie auf diese Weise auf eine Strukturkomponente zugreifen, kann sie an jeder Operandenposition verwendet werden, an der eine Variable des gleichen Typs verwendet werden kann. Die Komponente airport_from_id der Struktur connection im obigen Beispiel hat den Typ /DMO/AIRPORT_FROM_ID. Folglich können Sie diese Komponente an jeder Operandenposition verwenden, an der Sie eine einfache Variable des Typs /DMO/AIRPORT_FROM_ID verwenden können; und zwar nicht nur auf der linken Seite einer Wertzuweisung wie im Beispiel, sondern auch auf der rechten Seite, in der Parameterübergabe eines Methodenaufrufs, in der INTO- oder WHERE-Klausel einer SELECT-Anweisung usw.

Wenn die Komponente einer Struktur selbst eine Struktur ist, greifen Sie durch erneute Verwendung des Komponentenselektors nach dem Namen der Hauptkomponente auf die Unterkomponenten zu. Die erste Wertzuweisung im Beispiel greift auf die Komponente MSGTY von MESSAGE zu, die selbst eine Komponente der geschachtelten Struktur CONNECTION_NESTED ist.

Hinweis

Mit der Codevervollständigung können Sie den Zugriff auf Strukturkomponenten implementieren. Setzen Sie den Cursor direkt hinter den Strukturkomponentenselektor, und drücken Sie STRG + LEERTASTE, um eine Liste aller verfügbaren Strukturkomponenten anzuzeigen.

Mit dem Ausdruck VALUE #( ) können einem strukturierten Datenobjekt auf elegante Art Werte zugewiesen werden.

Wenn Sie eine gesamte Struktur füllen möchten, können Sie jede Komponente wie im vorherigen Beispiel einzeln adressieren.

Sie können aber auch einen Ausdruck VALUE #( ) zum Füllen der Struktur verwenden. Der Ausdruck konstruiert eine Struktur, füllt sie mit Werten und weist die gefüllte Struktur einer Variablen zu, in diesem Fall connection. Das Rautenzeichen (#) weist die ABAP-Laufzeitumgebung an, eine Struktur mit demselben Typ wie die Zielvariable connection zu konstruieren. In den Klammern führen Sie die Komponenten der Struktur auf, die gefüllt werden sollen (es müssen nicht alle sein), und weisen ihnen einen Wert zu.

Wenn Sie eine Struktur auf diese Weise füllen, löscht das Laufzeitsystem alle vorhandenen Werte aus der Struktur, bevor sie wieder mit den Werten aus Ihrem Ausdruck gefüllt wird.

Notiz

Eine Zuweisung in der Form connection = VALUE #( ). mit nur einem Leerzeichen zwischen den Klammern füllt alle Komponenten der Struktur mit dem typspezifischen Initialwert. Dies hat die gleiche Wirkung wie die Anweisung CLEAR connection.

In ABAP dürfen Sie den Inhalt einer Struktur nur dann direkt in eine andere Struktur mit der Notation <target structure> = <source structure> kopieren, wenn die beiden Strukturtypen kompatibel sind. Dies ist in der Regel nur dann der Fall, wenn beide Strukturen vom selben Typ sind. Wenn die Strukturen unterschiedliche Typen haben, können zwei Fälle eintreten:

  • Wenn eine der Strukturen eine nicht-zeichenartige Komponente an einer Stelle hat, an der die andere Struktur eine zeichenartige Komponente aufweist, führt die direkte Zuweisung zu einem Syntaxfehler.
  • Wenn beide Strukturen zeichenartig sind, d.h. beide Strukturen nur aus zeichenartigen Komponenten bestehen, ist eine direkte Zuweisung technisch möglich. In der Regel kommt es jedoch zu einem falschen Ergebnis.

Im Beispiel sind Quellstruktur und Zielstruktur zeichenartig. Daher ist eine direkte Zuordnung technisch möglich. Da sie jedoch nicht kompatibel sind, ist das Ergebnis falsch: Der Inhalt der Komponente carrier_name wird in die Komponente message in der Zielstruktur kopiert.

Da sich kein Syntaxfehler ergibt, müssen Sie besonders vorsichtig sein, wenn Sie mit nicht kompatiblen zeichenartigen Strukturen arbeiten.

Wenn Sie Daten zwischen Strukturen kopieren, möchten Sie in der Regel Informationen aus einem Feld in das entsprechende Feld der Zielstruktur kopieren - airport_from_id nach airport_from_id, airport_to_id nach airport_to_id usw. Um dies in ABAP zu erreichen, verwenden Sie den Ausdruck CORRESPONDING. Dadurch werden Werte aus <source_structure> den entsprechenden, d.h. namensgleichen Komponenten von <target_structure> zugeordnet. Sie müssen die folgenden Punkte beachten:

  • Die Felder müssen identische Namen haben.
  • Die Komponenten müssen sich nicht in beiden Strukturen in der gleichen Position oder Reihenfolge befinden.
  • Wenn die Felder unterschiedliche Typen aufweisen, versucht ABAP eine Typkonvertierung entsprechend dem vordefinierten Satz von Regeln.

Der CORRESPONDING -Ausdruck im Beispiel legt eine Struktur vom Typ st_connection_nested an. Der Struktur werden dann die Werte von gleichnamigen Komponenten aus der Struktur connection zugewiesen. Alle anderen Komponenten bleiben initial. Die so aufgebaute Struktur wird dann der connection_nested Struktur zugeordnet. Dadurch werden der Komponente message Initialwerte eingeschränkt zugeordnet.

Try It Out: Zugriff auf strukturierte Datenobjekte

  1. Legen Sie wie in der ersten Übung dieser Schulung eine neue globale Klasse an, die das Interface IF_OO_ADT_CLASSRUN implementiert.
  2. Kopieren Sie das folgende Code-Snippet in den Implementierungsteil der Methode if_oo_adt_classrun~main( ):
    Code Snippet
    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
    TYPES: BEGIN OF st_connection, airport_from_id TYPE /dmo/airport_from_id, airport_to_id TYPE /dmo/airport_to_id, carrier_name TYPE /dmo/carrier_name, END OF st_connection. TYPES: BEGIN OF st_connection_nested, airport_from_id TYPE /dmo/airport_from_id, airport_to_id TYPE /dmo/airport_to_id, message TYPE symsg, carrier_name TYPE /dmo/carrier_name, END OF st_connection_nested. DATA connection TYPE st_connection. DATA connection_nested TYPE st_Connection_nested. * Example 1: Access to structure components ********************************************************************** connection-airport_from_id = 'ABC'. connection-airport_to_id = 'XYZ'. connection-carrier_name = 'My Airline'. "Access to sub-components of nested structure connection_nested-message-msgty = 'E'. connection_nested-message-msgid = 'ABC'. connection_nested-message-msgno = '123'. * Example 2: Filling a structure with VALUE #( ). ********************************************************************** CLEAR connection. connection = VALUE #( airport_from_id = 'ABC' airport_to_id = 'XYZ' carrier_name = 'My Airline' ). " Nested VALUE to fill nested structure connection_nested = VALUE #( airport_from_id = 'ABC' airport_to_id = 'XYZ' message = VALUE #( msgty = 'E' msgid = 'ABC' msgno = '123' ) carrier_name = 'My Airline' ). * Example 3: Wrong result after direct assignment ********************************************************************** connection_nested = connection. out->write( `-------------------------------------------------------------` ). out->write( `Example 3: Wrong Result after direct assignment` ). out->write( data = connection name = `Source Structure:`). out->write( |Component connection_nested-message-msgid: { connection_nested-message-msgid }| ). out->write( |Component connection_nested-carrier_name : { connection_nested-carrier_name }| ). * Example 4: Assigning Structures using CORRESPONDING #( ) ********************************************************************** CLEAR connection_nested. connection_nested = CORRESPONDING #( connection ). " out->write( `-------------------------------------------------------------` ). out->write( `Example 4: Correct Result after assignment with CORRESPONDING` ). out->write( data = connection name = `Source Structure:`). out->write( |Component connection_nested-message-msgid: { connection_nested-message-msgid }| ). out->write( |Component connection_nested-carrier_name : { connection_nested-carrier_name }| ).
  3. Drücken Sie STRG + F3, um die Klasse zu aktivieren, und F9, um die Konsolen-App auszuführen.
  4. Analysieren Sie die Konsolenausgabe. Debuggen Sie das Programm, und probieren Sie mit dem Quelltext Verschiedenes aus, um sich mit den Konzepten vertraut zu machen.

Strukturierte Datenobjekte in ABAP SQL

Die INTO-Klausel der SELECT-Anweisung funktioniert nur dann richtig, wenn die Anzahl und die Typen der Strukturkomponenten der Anzahl und den Typen, die in der FIELDS-Klausel festgelegt sind, entsprechen. Im oben gezeigten Beispiel kann die Anweisung nur funktionieren, wenn die Struktur connection drei Komponenten mit dem gleichen Typ und der gleichen Länge aufweist wie die in der FIELDS-Klausel aufgeführten Spalten DepartureAirport, DestinationAirport und \_Airline-Name. Beachten Sie, dass die Namen in diesem Fall nicht identisch sein müssen – das System füllt die Zielstruktur von links nach rechts.

Wenn die Feldliste in der FIELDS-Klausel nicht mit der Struktur oder dem Tabellenzeilentyp in der INTO-Klausel übereinstimmt, kommt es zu einem Laufzeitfehler.

Das Beispiel zeigt eine einfache Technik, um sicherzustellen, dass die Zielstruktur mit der Feldauswahl übereinstimmt:

  • Die Zielstruktur ist mit der CDS-View /DMO/I_Connection typisiert, die die Datenquelle in der FROM-Klausel darstellt.
  • Das Sternchen (*) nach dem Schlüsselwort FIELDS ist eine kurze Notation, um sicherzustellen, dass alle Felder der View Teil der Feldauswahl sind. Exponierte Assoziationen werden ignoriert.

Notiz

Diese Technik steht auch beim direkten Lesen aus einer Datenbanktabelle zur Verfügung. Wie CDS-View-Definitionen können auch Definitionen von Datenbanktabellen als globale Strukturtypen in ABAP dienen.

Der Hauptvorteil dieser Technik besteht darin, dass die SELECT-Anweisung syntaktisch intakt bleibt, auch wenn Sie oder eine andere Person Änderungen an einer CDS-View oder Datenbanktabelle vornehmen. Der größte Nachteil besteht darin, dass immer alle Felder aus der Datenbank gelesen werden, unabhängig davon, ob sie tatsächlich benötigt werden oder nicht.

Notiz

Verwenden Sie diese Technik nur für Views und Tabellen mit wenigen Feldern und nur dann, wenn Sie tatsächlich alle Felder benötigen. Wenn unnötig Daten aus der Datenbank gelesen werden, kommt es häufig zu Performanceproblemen.

Eine weitere Möglichkeit, Syntaxfehler zu vermeiden, ist die Variante INTO CORRESPONDING FIELDS. Diese Variante hat die gleiche Wirkung wie der Operator CORRESPONDING #( ), den Sie bereits kennengelernt haben. Sie stellt sicher, dass Daten zwischen gleichnamigen Komponenten kopiert werden. Indem Sie den Strukturtyp Ihren Anforderungen entsprechend definieren, können Sie sicherstellen, dass nur die benötigten Daten gelesen werden.

Zur Erinnerung: Nur die Namen müssen identisch sein. Um Probleme zu vermeiden, sollten Sie jedoch darauf achten, dass gleichnamige Komponenten kompatible Typen haben. Anderenfalls versucht das System, die Inhalte des Quellfelds in den Typen des Zielfelds zu konvertieren. Dies kann zu Datenverlust oder (behandelbaren) Laufzeitfehlern führen.

Wenn die Feldnamen in der Datenquelle und die Komponentennamen in der Zielstruktur nicht übereinstimmen, funktioniert die Kombination von FIELDS * und INTO CORRESPONDING FIELDS OF nicht.

Wenn Sie die Variante INTO CORRESPONDING FIELDS OF beibehalten möchten, können Sie für die ausgewählten Felder in der Feldliste Aliasnamen definieren. Fügen Sie dazu hinter dem Feldnamen den Zusatz AS sowie anschließend den Aliasnamen hinzu. Im Beispiel lautet der Aliasname für das View-Feld DepartureAirport „airport_from_id" und der Aliasname für den Pfadausdruck \_Airline-Name „carrier_name". Basierend auf diesen Aliasnamen identifiziert INTO CORRESPONDING FIELDS OF korrekt die Strukturkomponente, in der die abgerufenen Daten gespeichert werden sollen.

Konflikte zwischen der Feldauswahl und der Zielstruktur lassen sich am einfachsten durch eine Inline-Deklaration in der INTO -Klausel vermeiden. Die Reihenfolge, der Typ und der Name der inline deklarierten Struktur werden aus der FIELDS-Klausel abgeleitet. Daher passt die Zielstruktur immer zur Feldauswahl.

Notiz

Inline-Deklarationen werden nur hinter INTO unterstützt. Hinter INTO CORRESPONDING FIELDS OF können keine Inline-Deklarationen verwendet werden.

Im Beispiel gibt es keinen Alias für das Feld DepartureAirport. Der Name des Feldes wird als Komponentenname in der Struktur connection_inline verwendet. Das Feld DestinationAirportsowie der Pfadausdruck \_Airline-Name haben optionale Aliasnamen (ArrivalAirport und AirlineName). Hier werden die Aliasnamen als Komponentennamen verwendet.

Bei der Arbeit mit einer relationalen Datenbank tritt häufig das Problem auf, dass zugehörige Daten aus verschiedenen Datenbanktabellen gelesen werden müssen. Wir hatten bereits gelernt, dass sich diese Aufgabe durch Assoziationen in CDS-Views elegant lösen lässt.

Wenn keine CDS-View mit geeigneten Assoziationen vorhanden ist, können stattdessen SQL-Joins implementiert werden. Das obige Beispiel veranschaulicht das Prinzip von Joins:

Wir interessieren uns für Flugverbindungen und die Flughäfen, die dadurch miteinander verbunden werden. Die dreistelligen IDs der Flughäfen finden Sie in der Datenbanktabelle /DMO/CONNECTION. Die vollständigen Namen der Flughäfen sind in der Datenbanktabelle /DMO/AIRPORT gespeichert.

Um eine Verbindung mit dem Namen des Abflughafens abzurufen, werden in einer SELECT-Anweisung die Verbindungsdaten aus der Datenbanktabelle /DMO/CONNECTION gelesen und mit der Datenbanktabelle /DMO/AIRPORT verknüpft.

Ein Join besteht aus folgenden Bestandteilen:

Datenquellen
Die Datenbanktabellen und Views, die miteinander verknüpft werden sollen. Ein einzelner Join verknüpft immer eine linke Datenquelle mit einer rechten Datenquelle. Im obigen Beispiel ist die Tabelle /DMO/CONNECTION die linke Datenquelle und die Tabelle /DMO/AIRPORT die rechte Datenquelle. ABAP SQL unterstützt auch Joins von Joins (geschachtelte Joins).
Join-Bedingung
Die Join-Bedingung gibt an, welche Datensätze der rechten Datenquelle zu einem Datensatz aus der linken Datenquelle gehören. Im obigen Beispiel wird der zugehörige Abflughafen durch den Wert in den Spalten CLIENT und AIRPORT_ID identifiziert. Die Join-Bedingung lautet:
/DMO/CONNECTION~CLIENT = /DMO/AIRPORT~CLIENT
AND
/DMO/CONNECTION~AIRPORT_FROM_ID = /DMO/AIRPORT~AIRPORT_ID
Join-Typ
Der Join-Typ hat Einfluss auf das Ergebnis, wenn eine der Datenquellen keine übereinstimmenden Datensätze enthält. ABAP SQL unterstützt derzeit INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN und CROSS JOIN. Der häufigste Join-Typ ist ein LEFT OUTER JOIN.

Die Abbildung zeigt die ABAP-SQL-Syntax für einen Join. In der FROM-Klausel wird der Join-Typ durch die Schlüsselwörter LEFT OUTER JOIN zwischen der linken Datenquelle /dmo/connection und der rechten Datenquelle /dmo/airport angegeben. Über die Syntax werden die Aliasnamen c und f für die Datenquellen eingebracht. Aliasnamen für Datenquellen sind optional, es sei denn, eine Datenquelle kommt mehr als einmal im Join vor.

Die Join-Bedingung folgt auf das Schlüsselwort ON. Das Trennzeichen zwischen der Datenquelle oder ihrem Alias und dem Feld ist das Tildezeichen (~).

Notiz

In ABAP SQL ist es nicht notwendig, die Mandantenfelder zu erwähnen. Sie werden von der Datenbankschnittstelle zur Join-Bedingung hinzugefügt, bevor die Anweisung an die Datenbank gesendet wird. Wenn die FROM-Klausel einen Join definiert, können Sie Felder aus beiden Datenquellen in den FIELDS- und WHERE-Klauseln verwenden.

In diesem Beispiel liest die SELECT -Anweisung nicht nur den Namen des Abflughafens, sondern auch den Namen des Zielflughafens. Hierfür definiert die FROM-Klausel einen verschachtelten Join:

Der erste Join ist ein Left Outer Join der Tabellen /dmo/connection und /dmo/airport, der den Alias „f" (wie „from") für die rechte Datenquelle einführt. Dieser erste Join wird dann als linke Datenquelle für einen zweiten Left Outer Join verwendet, der die Tabelle /dmo/airport als rechte Datenquelle hat. Beachten Sie, dass in diesem Fall der Alias „t" (für „to") entscheidend ist, um dieses Erscheinungsbild der Tabelle /dmo/airport von der vorherigen zu unterscheiden.

Die FIELDS-Klausel listet die Flughafennamen aus beiden Datenquellen auf und führt die Aliase airport_from_name und airport_to_name ein, um sie voneinander zu unterscheiden.

Hinweis

Die Klammern um den ersten Join sind optional. Wenn sie ausgelassen werden, werden die Joins in der FROM-Klausel von links nach rechts ausgewertet.

Try It Out: Strukturierte Datenobjekte in ABAP SQL

  1. Legen Sie wie in der ersten Übung dieser Schulung eine neue globale Klasse an, die das Interface IF_OO_ADT_CLASSRUN implementiert.
  2. Kopieren Sie das folgende Code-Snippet in den Implementierungsteil der Methode if_oo_adt_classrun~main( ):
    Code Snippet
    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
    TYPES: BEGIN OF st_connection, airport_from_id TYPE /dmo/airport_from_id, airport_to_id TYPE /dmo/airport_to_id, carrier_name TYPE /dmo/carrier_name, END OF st_connection. TYPES: BEGIN OF st_connection_short, DepartureAirport TYPE /dmo/airport_from_id, DestinationAirport TYPE /dmo/airport_to_id, END OF st_connection_short. DATA connection TYPE st_connection. DATA connection_short TYPE st_connection_short. DATA connection_full TYPE /DMO/I_Connection. * Example 1: Correspondence between FIELDS and INTO ********************************************************************** SELECT SINGLE FROM /DMO/I_Connection FIELDS DepartureAirport, DestinationAirport, \_Airline-Name WHERE AirlineID = 'LH' AND ConnectionID = '0400' INTO @connection. out->write( `------------------------------` ). out->write( `Example 1: Field List and INTO` ). out->write( connection ). * Example 2: FIELDS * ********************************************************************** SELECT SINGLE FROM /DMO/I_Connection FIELDS * WHERE AirlineID = 'LH' AND ConnectionID = '0400' INTO @connection_full. out->write( `----------------------------` ). out->write( `Example 2: FIELDS * and INTO` ). out->write( connection_full ). * Example 3: INTO CORRESPONDING FIELDS ********************************************************************** SELECT SINGLE FROM /DMO/I_Connection FIELDS * WHERE AirlineID = 'LH' AND ConnectionID = '0400' INTO CORRESPONDING FIELDS OF @connection_short. out->write( `----------------------------------------------------` ). out->write( `Example 3: FIELDS * and INTO CORRESPONDING FIELDS OF` ). out->write( connection_short ). * Example 4: Alias Names for Fields ********************************************************************** CLEAR connection. SELECT SINGLE FROM /DMO/I_Connection FIELDS DepartureAirport AS airport_from_id, \_Airline-Name AS carrier_name WHERE AirlineID = 'LH' AND ConnectionID = '0400' INTO CORRESPONDING FIELDS OF @connection. out->write( `---------------------------------------------------` ). out->write( `Example 4: Aliases and INTO CORRESPONDING FIELDS OF` ). out->write( connection ). * Example 5: Inline Declaration ********************************************************************** SELECT SINGLE FROM /DMO/I_Connection FIELDS DepartureAirport, DestinationAirport AS ArrivalAirport, \_Airline-Name AS carrier_name WHERE AirlineID = 'LH' AND ConnectionID = '0400' INTO @DATA(connection_inline). out->write( `-----------------------------------------` ). out->write( `Example 5: Aliases and Inline Declaration` ). out->write( connection_inline ). * Example 6: Joins ********************************************************************** SELECT SINGLE FROM ( /dmo/connection AS c LEFT OUTER JOIN /dmo/airport AS f ON c~airport_from_id = f~airport_id ) LEFT OUTER JOIN /dmo/airport AS t ON c~airport_to_id = t~airport_id FIELDS c~airport_from_id, c~airport_to_id, f~name AS airport_from_name, t~name AS airport_to_name WHERE c~carrier_id = 'LH' AND c~connection_id = '0400' INTO @DATA(connection_join). out->write( `------------------------------------------` ). out->write( `Example 6: Join of Connection and Airports` ). out->write( connection_join ).
  3. Drücken Sie STRG + F3, um die Klasse zu aktivieren, und F9, um die Konsolen-App auszuführen.
  4. Analysieren Sie die Konsolenausgabe. Debuggen Sie das Programm, und probieren Sie mit dem Quelltext Verschiedenes aus, um sich mit den Konzepten vertraut zu machen.

Ein strukturiertes Datenobjekt verwenden

In dieser Übung deklarieren Sie ein strukturiertes Attribut, füllen es mittels einer SELECT-Anweisung und greifen auf die Strukturkomponenten zu.

Vorlage:

  • /LRN/CL_S4D400_DBS_CDS (globale Klasse)

Lösung:

  • /LRN/CL_S4D400_STS_STRUCTURE (globale Klasse)

Aufgabe 1: Vorlage kopieren

Kopieren Sie die Vorlageklasse. Alternativ können Sie Ihre Lösung aus der vorherigen Übung kopieren.

Schritte

  1. Kopieren Sie die Klasse /LRN/CL_S4D400_DBS_CDS in eine Klasse in Ihrem eigenen Paket (Namensvorschlag: ZCL_##_STRUCTURE, wobei ## für Ihre Gruppennummer steht).

    1. Öffnen Sie den Quelltext der globalen Klasse /LRN/CL_S4D400_DBS_CDS.

    2. Verknüpfen Sie die View Project Explorer mit dem Editor.

    3. Klicken Sie in der View Project Explorer mit der rechten Maustaste auf die Klasse /LRN/CL_S4D400_DBS_CDS, um das Kontextmenü zu öffnen.

    4. Wählen Sie im Kontextmenü Duplicate ...

    5. Geben Sie den Namen Ihres Pakets in das Feld Package ein. Geben Sie im Feld Name den Namen ZCL_##_STRUCTURE ein, wobei ## für Ihre Gruppennummer steht.

    6. Passen Sie die Beschreibung an, und wählen Sie Next.

    7. Bestätigen Sie den Transportauftrag, und wählen Sie Finish.

Aufgabe 2: Ein strukturiertes Datenobjekt deklarieren

Deklarieren Sie in der lokalen Klasse ein strukturiertes Attribut details, um die skalaren Attribute airport_from_id, airport_to_id und carrier_name zu ersetzen. Beginnen Sie mit der Definition eines privaten Strukturtyps st_details in der lokalen Klasse.

Schritte

  1. Wechseln Sie in die lokale Klasse lcl_connection.

    1. Wählen Sie in der globalen Klasse Local Types.

  2. Definieren Sie einen privaten Strukturtyp st_details mit folgenden Komponenten:

    Komponenten des Strukturtyps st_details:

    KomponentennameDatentyp
    DepartureAirport/dmo/airport_from_id
    DestinationAirport/dmo/airport_to_id
    AirlineName/dmo/carrier_name
    1. Fügen Sie nach der Zeile PRIVATE SECTION. den folgenden Code hinzu:

      Code Snippet
      12345678
      TYPES: BEGIN OF st_details, DepartureAirport TYPE /dmo/airport_from_id, DestinationAirport TYPE /dmo/airport_to_id, AirlineName TYPE /dmo/carrier_name, END OF st_details.
  3. Kommentieren oder entfernen Sie die Deklaration der Attribute airport_from_id, airport_to_id und carrier_name.

    1. Wählen Sie die Zeilen mit den drei DATA-Anweisungen aus.

    2. Drücken Sie Strg + <, um vor jeder ausgewählten Zeile ein Sternchen (*) hinzuzufügen.

  4. Deklarieren Sie ein neues privates Instanzattribut details, und typisieren Sie es mit dem Strukturtyp st_details.

    1. Passen Sie den Quelltext wie folgt an:

      Code Snippet
      123456789
      * DATA airport_from_id TYPE /dmo/airport_from_id. * DATA airport_to_id TYPE /dmo/airport_to_id. * * DATA carrier_name TYPE /dmo/carrier_name. DATA details TYPE st_details.

Aufgabe 3: Auf Strukturkomponenten zugreifen

Verwenden Sie die Komponenten des strukturierten Attributs details in der Methode get_output.

Schritte

  1. Passen Sie die Implementierung der Methode get_output an. Ersetzen Sie den Zugriff auf die Attribute airport_from_id, airport_to_id und carrier_name durch die entsprechende Komponente des Attributs details.

    Hinweis

    Geben Sie die Komponentennamen nicht manuell ein! Nachdem Sie den Strukturkomponentenselektor (-) eingegeben haben, drücken Sie Strg + Leertaste, um eine Liste aller Komponenten aufzurufen.
    1. Navigieren Sie zur Implementierung der Methode get_output.

    2. Passen Sie die APPEND-Anweisungen wie folgt an:

      Code Snippet
      12345678910111213
      * APPEND |--------------------------------| TO r_output. * APPEND |Carrier: { carrier_id } { carrier_name }| TO r_output. * APPEND |Connection: { connection_id }| TO r_output. * APPEND |Departure: { airport_from_id }| TO r_output. * APPEND |Destination: { airport_to_id }| TO r_output. APPEND |--------------------------------| TO r_output. APPEND |Carrier: { carrier_id } { details-airlinename }| TO r_output. APPEND |Connection: { connection_id }| TO r_output. APPEND |Departure: { details-departureairport }| TO r_output. APPEND |Destination: { details-destinationairport }| TO r_output.

Aufgabe 4: Das strukturierte Attribut in der SELECT-Anweisung füllen

Verwenden Sie das strukturierte Attribut als Ziel der SELECT -Anweisung in der Methode constructor.

Schritte

  1. Passen Sie die SELECT-Anweisung in der Implementierung der Methode constructor an. Ersetzen Sie die Liste der Datenobjekte in der INTO-Klausel durch das strukturierte Attribut details.

    1. Navigieren Sie zur Implementierung der Methode constructor.

    2. Passen Sie die SELECT-Anweisung wie folgt an:

      Code Snippet
      123456789
      SELECT SINGLE FROM /DMO/I_Connection FIELDS DepartureAirport, DestinationAirport, \_Airline-Name WHERE AirlineID = @i_carrier_id AND ConnectionID = @i_connection_id * INTO ( @airport_from_id, @airport_to_id, @carrier_name ). INTO @details.
  2. Optional: Verwenden Sie die Syntaxvariante INTO CORRESPONDING FIELDS OF @details..

    1. Ersetzen Sie INTO @details. in der SELECT-Anweisung durch den folgenden Code:

      Code Snippet
      123
        INTO CORRESPONDING FIELDS OF @details.
    2. Fügen Sie den Aliasnamen AirlineName für den Pfadausdruck hinzu.

    3. Die SELECT-Anweisung sollte nun wie folgt aussehen:

      Code Snippet
      12345678
      SELECT SINGLE FROM /DMO/I_Connection FIELDS DepartureAirport, DestinationAirport, \_Airline-Name as AirlineName WHERE AirlineID = @i_carrier_id AND ConnectionID = @i_connection_id INTO CORRESPONDING FIELDS OF @details.
  3. Aktivieren Sie die Klasse. Führen Sie sie aus, und analysieren Sie die Konsolenausgabe. Prüfen Sie, ob die Ausgabe Daten für alle Attribute anzeigt.

    1. Drücken Sie Strg + F3, um die Klasse zu aktivieren.

    2. Drücken Sie F9, um die Klasse auszuführen.