Core Data Services (CDS) ABAP

CDS SQL

die wichtigsten Elemente der SELECT Anweisung

(C) Brandeis Consulting

High Level Syntax CDS Views

DEFINE VIEW 
[<Parameters>]
AS SELECT FROM <Quelle>
[<Joins>]
[<Associations>]
{
  <Fieldlist>
}
[<WHERE Clause>]
[<GROUP BY Clause>]
[<HAVING Clause>]
(C) Brandeis Consulting

Feldliste

  • Zwischen geschweiften Klammern
  • Elemente durch Komma getrennt
  • Namen der Felder entweder
    • Aus dem Quellfeld oder
    • Per AS vergeben
  • Schlüsselfelder mit KEY
  • Ausdrücke zur Berechnung des Feldes

Beispiel

@AbapCatalog.sqlViewName: 'ZSQL_MINIMALasdf'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Minimal CDS definition'
define view zcds_minimal as select from snwd_so {
    key client     as Client,
    key so_id      as SoId,
    created_at     as CreatedAt,
    changed_at     as ChangedAt,
    currency_code  as CurrencyCode,
    gross_amount   as GrossAmount,
    net_amount     as NetAmount,
    tax_amount     as TaxAmount,
    overall_status as OverallStatus,
    payment_method as PaymentMethod,
    payment_terms  as PaymentTerms
}
(C) Brandeis Consulting

Ausdrücke

Ein Ausdruck ist in vielen Programmiersprachen ein Konstrukt, das gemäß einer gegebenen Semantik in Bezug auf einen Kontext ausgewertet werden kann, also einen Wert liefert.
In vielen formalen Sprachen sind Ausdrücke eines der wichtigsten Konstrukte, wenn nicht gar das einzige.

Wikipedia: Ausdruck (Programmierung)

Ein Ausdruck in SQL ist etwas, das zur Laufzeit einen Wert liefert.
Zur Designzeit ist der Datentyp, den der Ausdruck zurück geben wird, bekannt.

(C) Brandeis Consulting

Ausdrücke in der Feldliste

  • Felder von Quelltabellen
  • Literale - Festwerte, entweder als Zeichenkette in Hochkomma oder als Zahl
  • Session Variablen - Zugriff über $session.vname
  • Aggregatausdrücke - MIN( ), MAX( ), AVG( ), SUM( ), COUNT([DISTINCT] )
  • Operatorausdrücke - Plus, Minus, Mal, (Geteilt)
  • SQL-Funktionen
  • CASE-Ausdrücke
  • Pfadausdrücke
(C) Brandeis Consulting

Ausdrücke in der Feldliste - Beispiele

@AbapCatalog.sqlViewName: 'ZJB_EXPRESSIONS'

@EndUserText.label: 'SQL Expressions'
define view zjb_cds_expressions
  as select from zbc_users as u
  
  left outer join zjb_cds_aggregation as t
  on u.user_id = t.Assignee
{
  key u.user_id       as UserId,
      u.firstname     as Firstname,
      u.lastname      as Lastname,
      u.email         as Email,
      u.gender        as Gender,
      u.date_of_birth as DateOfBirth,
      u.changed_at    as ChangedAt,
      
      'EUR'         as CurrencyCode,      
      $session.user as CurrentUser,      
      concat_with_space( Left(u.firstname, 1) ,  u.lastname , 1 ) as Name,      
      case u.gender when 'F' then 'Frau '
                  when 'M' then 'Herr '
                  else '' end 
                  
                  as Anrede,                  
      concat_with_space( concat_with_space( 'User hat ', 
                                            cast( t.TaskCount as abap.char(11) ) , 
                                            1 ), 
                         ' Aufgaben', 
                         1 ) as CNT
}
(C) Brandeis Consulting

Session Variablen

Werte aus der SY-Struktur des ABAP

  • $session.user - SY-UNAME
  • $session.client - SY-MANDT
  • $session.system_language - SY-LANGU
  • $session.system_date - SY-DATUM
  • $session.USER_TIMEZONE
  • $session.USER_DATE

Die Variablen sind nur bei Zugriffen aus dem ABAP belegt.

(C) Brandeis Consulting

SQL-Funktionen

Es kommen mit jedem Release mehr hinzu.

  • Datentyp spezifische
    • Zeichenketten
    • Datum und Zeit
    • Numerische Daten
  • Konvertierung zwischen den Datentypen
(C) Brandeis Consulting

SQL-Funktionen für Zeichenketten

Die übliche Verdächtigen...

SQL-Funktion Argument 1 Argument 2 Argument 3
CONCAT Zeichenkette 1 Zeichenkette 2
CONCAT_WITH_SPACE Zeichenkette 1 Zeichenkette 2 # Spaces
LENGTH Zeichenkette
LEFT Zeichenkette Länge
RIGHT Zeichenkette Länge
SUBSTRING Zeichenkette 1.Zeichen Länge
LOWER Zeichenkette
UPPER Zeichenkette
INSTR Zeichenkette Suchstring
REPLACE Zeichenkette Suchstring Ersatz
LPAD Zeichenkette Länge Muster
RPAD Zeichenkette Länge Muster
LTRIM Zeichenkette Zeichen
RTRIM Zeichenkette Zeichen
(C) Brandeis Consulting

SQL-Funktionen für numerische Werte

Neben den üblichen arithmetischen Operatoren +, -, * und /

Kategorie SQL-Funktion Argument 1 Argument 2 Argument 3 Ergebnis
Vorzeichen ABS Wert Betrag des Wert
Division DIV Zähler Nenner Ganzzahl
DIVISION Zähler Nenner Dezimalstellen Dezimalzahl
MOD Zähler Nenner Divisionsrest
Runden ROUND Wert NK-Stellen Wert gerundet
CEIL Wert Ganzzahl
FLOOR Wert Ganzzahl
Konvertieren UNIT_CONVERSION
CURRENCY_CONVERSION
DECIMAL_SHIFT
(C) Brandeis Consulting

SQL-Funktionen für Datum und Zeit

Bei vielen SQL-Funktionen muss ein Fehlerverhalten (<on_error>) mit angegeben. Möglich sind die Werte FAIL, INITIAL, NULL , bei ADD-Funktionen auch UNCHANGED .

Bei vielen SQL-Funktion muss die Zeitzone angegeben werden. Diese kann entweder konstant (z.B. CET) sein oder sie wird von den folgenden beiden Funktionen bereitgestellt:

  • ABAP_SYSTEM_TIMEZONE(<Client>, <on_error>)
  • ABAP_USER_TIMEZONE(<User>, <Client>, <on_error>)

User und Client kann man aus den Sitzungsvariablen beziehen:

  • $session.user
  • $session.client
(C) Brandeis Consulting

SQL-Funktionen für die Zeitberechnung

Kategorie SQL-Funktion Argument 1 Argument 2 Argument 3 Argument 4 Argument 5
Addition von Zeit DATS_ADD_DAYS Datum #Tage OnError
DATS_ADD_MONTHS Datum #Monate OnError
TSTMP_ADD_SECONDS Zeitstempel #Sekunden OnError
Differenzen DATS_DAYS_BETWEEN Datum Datum
TSTMP_SECONDS_BETWEEN Zeitstempel Zeitstempel
Gültigkeit DATE_IS_VALID Datum
TIMS_IS_VALID Uhrzeit
TSTMP_IS_VALID Zeitstempel
Konvertierung DATS_TIMS_TO_TSTMP Datum Uhrzeit Zeitzone Mandant OnError
TSTMP_TO_DATS Zeitstempel Zeitzone Mandant OnError
TSTMP_TO_TIMS Zeitstempel Zeitzone Mandant OnError
Zeitzonen ABAP_SYSTEM_TIMEZONE Mandant OnError
ABAP_USER_TIMEZONE User Mandant OnError
Aktueller UTC-Zeitstempel TSTMP_CURRENT_UTCTIMESTAMP
(C) Brandeis Consulting

Typkonvertierung mit CAST und FLTP_TO_DEC

Typkonvertierung mit

  • CAST (<Wert> AS <Datentyp> )
  • FLTP_TO_DEC( <Float-Wert> AS <DEC-Datentyp> )

Der Wert kann ein beliebiger Ausdruck sein. Als Datentyp kommt in Frage:

  • Ein Datenelement
  • Ein eingebauter ABAP Datentyp mittels abap.<datentyp>

CAST-Beispiel

CAST( so.created_at AS abap.char(23))

(C) Brandeis Consulting

Operatorausdrücke

Addition, Subtraktion & Multiplikation eigentlich wie gewohnt, aber…

Falls bei einer Multiplikation die Anzahl der Stellen > 37, dann kommt diese Meldung:

Fehlermeldung, wenn die Anzahl der Stellen der Multiplikation > 37 sein kann

Dann müssen die Faktoren vor der Multiplikation in einen kleineren Typ konvertiert werden.

Bei CDS View Entities kommt die Fehlermeldung nicht mehr. Es kann nun auch ein Ergebnis mit mehr als 37 Stellen geben.

Division mit "/" ist nur bei Float-Datentypen möglich!
Statt dessen sollte die SQL-Funktion DIVISION(Zaehler, Nenner, #NK-Stellen) verwendet werden.

(C) Brandeis Consulting

CASE Ausdrücke - Einfach

Der CASE Ausdruck liefert genau einen Wert:

CASE Wert
        WHEN Vergleichswert1 THEN Ergebniswert1
        WHEN Vergleichswert2 THEN Ergebniswert2
        ...
        ELSE AlternativWert
    END

Überall wo hier Wert steht, kann ein beliebiger Ausdruck sein…

(C) Brandeis Consulting

CASE WHEN Ausdrücke - Komplex

 CASE   WHEN Bedingung1 THEN Ergebniswert1
        WHEN Bedingung2 THEN Ergebniswert2
        ...
        ELSE AlternativWert
    END

Die Bedingungen können sich auf unterschiedliche Spalten und Ausdrücke beziehen. Wenn mehr als eine Bedingung nach TRUE ausgewertet wird, so wird der erste Ergebniswert zurückgegeben.

(C) Brandeis Consulting

Demo - Ausdrücke in Feldlisten

@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Demo Ausdrücke in der Feldliste'
@ObjectModel.usageType:{
    serviceQuality: #X,
    sizeCategory: #S,
    dataClass: #MIXED
}
define view entity zi_demo_expressions
  as select from zbc_users
{
  key user_id            as UserId,
      concat_with_space( concat(left(firstname, 1), '.'), lastname, 1) as Name,
      lower(email)              as Email,
      case gender when 'F' then 'Frau'
                  when 'M' then 'Herr'
                  else ''
                  end             as Greeting,
      cast(left($session.system_date, 4) as abap.int4) 
        - cast(left(date_of_birth, 4) as abap.int4)      as Age
}
(C) Brandeis Consulting

Übung - Ausdrücke in Feldlisten

Erstelle eine CDS View Entity auf die Aufgaben in ZBC_TASKS. Erzeuge die folgenden Spalten:

  • TaskKey
  • SummaryShort - Die ersten 20 Zeichen der Spalte Summary plus 3 Punkte
    Phasellus sit amet e...
  • PrioCat - Prioritätenkategorie:
    • A - Priority > 90
    • B - Priority > 60
    • C - Rest
  • DaysToDueDate - Anzahl Tage bis Fälligkeit
  • TaskNumber - TaskKey ohne Projekt und Bindestrich (Fortgeschritten)

Manche Konstellationen von Ausdrücken funktionieren in CDS Views nicht, aber in CDS View Entities.

(C) Brandeis Consulting

Aggregation

Mit der GROUP BY-Klausel kann die Granularität der Daten verändert werden. Für jede Kombination von Werten aus den Feldern aus dieser Klausel wird eine Zeile in der Ergebnismenge gebildet.

Falls keine GROUP BY-Klausel verwendet wird, besteht die Ergebnismenge aus genau einer Zeile.

Alle Felder in der Feldliste müssen entweder:

  • In der GROUP BY Klausel vorkommen oder
  • mit einer Aggregatfunktion auf einen Einzelwert reduziert werden.
SELECT FROM <Quelle>
{
  <Gruppierungsfeld1>, 
  <Gruppierungsfeld2>,
  ...
  <Aggregatfunktion>(<Feld3>)
}
GROUP BY <Gruppierungsfeld1>,
         <Gruppierungsfeld2>
(C) Brandeis Consulting

UNION (ALL)

Mit UNION bilden wir die Vereinigungsmenge zwischen zwei Abfragen.

Voraussetzung

Beide Abfragen müssen

  • die gleiche Anzahl an Spalten haben
  • die gleichen Spantennamen haben
  • Kompatible Datentypen in den Spalten haben
DEFINE VIEW AS
<Abfrage1>
UNION [ALL]
<Abfrage2>

Unterschied UNION und UNION ALL

Der UNION-Operator entfernt Duplikate aus der Ergebnismenge. Der UNION ALL-Operator ist schneller, da hier keine Duplikate entfernt werden.

(C) Brandeis Consulting

WHERE -Klausel

Eingeschränkte Möglichkeiten im Vergleich zu SQLScript

  • Vergleichsprädikate (<, <=, …)
  • BETWEEN
  • IN-Prädikat, zum Vergleich mit einer Menge, z.B. WHERE type IN ('A', 'B', 'C')
  • LIKE - Suchen mit Platzhalter: % steht für 0-N beliebige Zeichen, _ steht für genau ein Zeichen.
  • IS NULL - Datenbank NULL Werte, z.B aus OUTER JOIN
  • IS INITIAL - ABAP Initialwert

Prädikate mit Unterabfragen sind nicht möglich. Diese müssen durch geschickte JOINs simuliert werde:

  • EXISTS-Prädikat:
    • WHERE EXISTS durch INNER JOIN
    • WHERE NOT EXISTS durch LEFT OUTER JOIN mit Filter auf IS NULL
  • WHERE Feld IN (Sub-Query) durch INNER JOIN
(C) Brandeis Consulting

NULL

Während der Berechnung des Ergebnis einer Abfrage in der Datenbank, kann der "Wert" NULL entstehen. Ursachen hierfür können sein:

  • NULL-Werte in der Datenbank - kommt relativ selten vor
  • Bei einem CASE-Ausdruck wurde kein ELSE-Zweig definiert
  • Bei einem OUTER JOIN wurde kein passender Datensatz anhand der ON-Klausel gefunden

Wenn NULL in der Ergebnismenge einer Abfrage vorkommt, dann wird der Wert durch den entsprechenden Initialwert im ABAP ersetzt.

NULL in Ausdrücken

Jede Berechnung mit NULL und immer wenn NULL in SQL-Fukntionen oder CASE-Ausdrücken vorkommt, ist das Ergebnis auch wiederum NULL.

(C) Brandeis Consulting

Umgang mit NULL

  • In der Feldliste - Um den Feldwert NULL durch einen anderen Wert zu ersetzen, kann die Funktion COALESCE(Wert, Ersatzwert) verwendet werden.
  • Beim Filtern - Um Zeilen mit NULL-Werten auszufiltern, muss das IS NULL-Prädikat verwendet werden.

NULL im ABAP

Im ABAP wird NULL durch den passenden Initialwert ersetzt.

(C) Brandeis Consulting