Tabellen in ABAP Cloud: Von SE11 zu CDS-basierter Definition

Kategorie
ABAP Cloud
Veröffentlicht
Autor
Johannes

In Classic ABAP war die SE11 das zentrale Werkzeug für Tabellendefinitionen. In ABAP Cloud sieht das anders aus: Tabellen werden direkt im Code als DDL Source definiert, aktiviert über die ABAP Development Tools (ADT). Dieser Artikel zeigt den Umstieg von der klassischen SE11-Welt zur modernen CDS-basierten Tabellendefinition.

Das Problem: SE11 in ABAP Cloud?

Wer in ABAP Cloud eine Transaktion SE11 sucht, wird nicht fündig:

SE11? → Gibt es nicht in ABAP Cloud
SE16? → Gibt es nicht in ABAP Cloud
SM30? → Gibt es nicht in ABAP Cloud

Alle Datendefinitionen erfolgen über ADT (Eclipse) und DDL Source Files.

Tabellendefinition im Vergleich

Classic ABAP (SE11)

Transaktion SE11 → Datenbanktabelle → ZFLIGHT_BOOK
Felder:
MANDT CLNT Mandant
BOOKING_ID NUMC(10) Buchungsnummer
FLIGHT_ID NUMC(10) Flugnummer
CUSTOMER_ID NUMC(10) Kundennummer
BOOKING_DATE DATS Buchungsdatum
PRICE CURR(15,2) Preis
CURRENCY CUKY Währung
STATUS CHAR(1) Status
→ Aktivieren → Datenbanktabelle angelegt

ABAP Cloud (DDL Source)

@EndUserText.label: 'Flugbuchungen'
@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE
@AbapCatalog.tableCategory: #TRANSPARENT
@AbapCatalog.deliveryClass: #A
@AbapCatalog.dataMaintenance: #RESTRICTED
define table zflight_book {
key client : abap.clnt not null;
key booking_id : abap.numc(10) not null;
flight_id : abap.numc(10);
customer_id : abap.numc(10);
booking_date : abap.dats;
@Semantics.amount.currencyCode: 'zflight_book.currency_code'
price : abap.curr(15,2);
currency_code: abap.cuky;
status : abap.char(1);
}

Vorteile der DDL-Syntax:

  • Versionierbar mit Git (siehe abapGit)
  • Keine GUI-Abhängigkeit
  • Annotationen direkt am Feld
  • Bessere Lesbarkeit im Code-Review

Tabelle anlegen in ADT

Schritt-für-Schritt

1. Rechtsklick auf Paket → New → Other ABAP Repository Object
2. Dictionary → Database Table
3. Name eingeben: ZFLIGHT_BOOK
4. Beschreibung: Flugbuchungen
5. Finish → DDL Source wird generiert

Grundgerüst einer Tabelle

@EndUserText.label: 'Beschreibung der Tabelle'
@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE
@AbapCatalog.tableCategory: #TRANSPARENT
@AbapCatalog.deliveryClass: #A
@AbapCatalog.dataMaintenance: #RESTRICTED
define table ztabelle {
key client : abap.clnt not null;
key key_field : <datentyp> not null;
field1 : <datentyp>;
field2 : <datentyp>;
}

Wichtige Annotationen

AnnotationBedeutungWerte
@AbapCatalog.tableCategoryTabellenart#TRANSPARENT, #STRUCTURE
@AbapCatalog.deliveryClassAuslieferungsklasse#A (Anwendungsdaten), #C (Customizing)
@AbapCatalog.dataMaintenancePflegeerlaubnis#RESTRICTED, #ALLOWED
@AbapCatalog.enhancement.categoryErweiterbarkeit#NOT_EXTENSIBLE, #EXTENSIBLE_ANY

Built-in Datentypen in ABAP Cloud

In ABAP Cloud werden Datentypen direkt mit abap.<typ> referenziert:

Häufig verwendete Typen

" Zeichenketten
field_char : abap.char(30); " Feste Länge
field_string : abap.string(256); " Variable Länge
field_numc : abap.numc(10); " Numerischer Text (z.B. IDs)
field_lang : abap.lang; " Sprachschlüssel
" Zahlen
field_int : abap.int4; " Integer (4 Byte)
field_int8 : abap.int8; " Integer (8 Byte)
field_dec : abap.dec(10,2); " Dezimalzahl
field_curr : abap.curr(15,2); " Währungsbetrag
field_quan : abap.quan(13,3); " Mengenfeld
" Datum und Zeit
field_date : abap.dats; " Datum (YYYYMMDD)
field_time : abap.tims; " Zeit (HHMMSS)
field_tstmp : abap.utclong; " UTC-Zeitstempel (empfohlen!)
" Sonstige
field_bool : abap_boolean; " Boolean (X oder leer)
field_client : abap.clnt; " Mandant
field_cuky : abap.cuky; " Währungsschlüssel
field_unit : abap.unit(3); " Mengeneinheit

Zeitstempel: UTCLONG bevorzugen

" ❌ Alt: Separates Datum und Zeit
created_date : abap.dats;
created_time : abap.tims;
" ✅ Neu: UTC-Zeitstempel
created_at : abap.utclong;
changed_at : abap.utclong;

Der Typ abap.utclong speichert Zeitstempel zeitzonen-unabhängig und ist der Standard für ABAP Cloud.

Datenelemente und Domänen

Classic ABAP: Getrennte Objekte

SE11 → Domäne → ZBOOKING_STATUS
Datentyp: CHAR(1)
Wertebereich: O (Open), C (Confirmed), X (Cancelled)
SE11 → Datenelement → ZBOOKING_STATUS
Domäne: ZBOOKING_STATUS
Feldbezeichner: Buchungsstatus
SE11 → Tabelle → ZFLIGHT_BOOK
STATUS → Datenelement ZBOOKING_STATUS

ABAP Cloud: Integrierte Definition

In ABAP Cloud werden Datenelemente als DDL Source definiert:

@EndUserText.label: 'Buchungsstatus'
@EndUserText.heading: 'Status'
define type zbooking_status : abap.char(1)

Domäne mit Festwerten

Für feste Wertevorräte gibt es das Enumeration-Konzept:

" Enumeration für Buchungsstatus
CLASS zcl_booking_status DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ENUM booking_status,
open VALUE IS INITIAL,
confirmed,
cancelled,
END OF ENUM booking_status.
ENDCLASS.

Oder direkt als CDS-Type:

@EndUserText.label: 'Buchungsstatus'
define type zbooking_status : abap.char(1)
enum {
open = 'O';
confirmed = 'C';
cancelled = 'X';
}

Vollständiges Flugbuchungs-Beispiel

Haupttabelle: Buchungen

@EndUserText.label: 'Flugbuchungen'
@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE
@AbapCatalog.tableCategory: #TRANSPARENT
@AbapCatalog.deliveryClass: #A
@AbapCatalog.dataMaintenance: #RESTRICTED
define table zflight_book {
key client : abap.clnt not null;
key booking_id : abap.numc(10) not null;
" Fachliche Schlüssel
flight_id : abap.numc(10);
customer_id : abap.numc(10);
" Buchungsdaten
booking_date : abap.dats;
@Semantics.amount.currencyCode: 'zflight_book.currency_code'
price : abap.curr(15,2);
currency_code : abap.cuky;
seats_booked : abap.int4;
booking_status : abap.char(1);
" Administrative Felder
created_by : abap.uname;
created_at : abap.utclong;
last_changed_by : abap.uname;
last_changed_at : abap.utclong;
local_last_changed: abap.utclong;
}

Stammdatentabelle: Flüge

@EndUserText.label: 'Flugdaten'
@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE
@AbapCatalog.tableCategory: #TRANSPARENT
@AbapCatalog.deliveryClass: #A
@AbapCatalog.dataMaintenance: #RESTRICTED
define table zflight {
key client : abap.clnt not null;
key flight_id : abap.numc(10) not null;
" Flugdaten
carrier_id : abap.char(3);
connection_id : abap.numc(4);
flight_date : abap.dats;
" Strecke
departure_city : abap.char(30);
departure_code : abap.char(3);
arrival_city : abap.char(30);
arrival_code : abap.char(3);
" Kapazität
seats_max : abap.int4;
seats_occupied : abap.int4;
" Preis
@Semantics.amount.currencyCode: 'zflight.currency_code'
base_price : abap.curr(15,2);
currency_code : abap.cuky;
}

Stammdatentabelle: Kunden

@EndUserText.label: 'Kundenstammdaten'
@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE
@AbapCatalog.tableCategory: #TRANSPARENT
@AbapCatalog.deliveryClass: #A
@AbapCatalog.dataMaintenance: #RESTRICTED
define table zcustomer {
key client : abap.clnt not null;
key customer_id : abap.numc(10) not null;
" Kundendaten
first_name : abap.char(40);
last_name : abap.char(40);
email : abap.char(100);
phone : abap.char(30);
" Adresse
street : abap.char(60);
city : abap.char(40);
postal_code : abap.char(10);
country : abap.char(3);
}

Table Entities: Die neue Architektur

Mit ABAP Cloud 2024 wurde das Konzept der Table Entities eingeführt. Dabei wird die Tabelle selbst zum Entity - ohne zusätzliche CDS View.

Klassischer Ansatz (drei Objekte)

1. Datenbanktabelle (ZFLIGHT_BOOK)
2. CDS View (ZI_FlightBooking)
3. Behavior Definition (ZI_FlightBooking)

Table Entity Ansatz (zwei Objekte)

1. Table Entity (ZI_FlightBooking) - Tabelle + View in einem
2. Behavior Definition (ZI_FlightBooking)

Table Entity Definition

@EndUserText.label: 'Flugbuchung (Table Entity)'
@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE
define table entity zi_flightbooking {
key client : abap.clnt not null;
key booking_id : abap.numc(10) not null;
flight_id : abap.numc(10);
customer_id : abap.numc(10);
booking_date : abap.dats;
@Semantics.amount.currencyCode: 'zi_flightbooking.currency_code'
price : abap.curr(15,2);
currency_code : abap.cuky;
booking_status : abap.char(1);
created_by : abap.uname;
created_at : abap.utclong;
last_changed_by : abap.uname;
last_changed_at : abap.utclong;
local_last_changed: abap.utclong;
}

Vergleich: Tabelle vs. Table Entity

AspektTabelle + CDS ViewTable Entity
Objekte2 (Tabelle + View)1
WartungDoppelte PflegeEinmal definieren
FlexibilitätHochEingeschränkt
AliaseFrei wählbarFeldname = Spaltenname
Berechnete FelderJaNein
Empfohlen fürKomplexe ModelleEinfache CRUD

Mehr zum CDS Pattern findest du im kommenden Artikel über RAP CDS Pattern.

Foreign Keys und Assoziationen

Foreign Key in Tabellendefinition

In ABAP Cloud werden Foreign Keys über Annotationen definiert:

@EndUserText.label: 'Flugbuchungen mit Foreign Keys'
define table zflight_book_fk {
key client : abap.clnt not null;
key booking_id : abap.numc(10) not null;
@AbapCatalog.foreignKey.screenCheck: false
flight_id : abap.numc(10)
with foreign key zflight
where client = zflight_book_fk.client
and flight_id = zflight_book_fk.flight_id;
@AbapCatalog.foreignKey.screenCheck: false
customer_id : abap.numc(10)
with foreign key zcustomer
where client = zflight_book_fk.client
and customer_id = zflight_book_fk.customer_id;
" ... weitere Felder
}

Assoziationen in CDS Views

Für RAP-Anwendungen sind Assoziationen in der CDS View der bessere Weg:

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Flugbuchungen mit Assoziationen'
define root view entity ZI_FlightBooking
as select from zflight_book as Booking
association [1..1] to ZI_Flight as _Flight
on $projection.FlightId = _Flight.FlightId
association [1..1] to ZI_Customer as _Customer
on $projection.CustomerId = _Customer.CustomerId
{
key Booking.booking_id as BookingId,
Booking.flight_id as FlightId,
Booking.customer_id as CustomerId,
Booking.booking_date as BookingDate,
@Semantics.amount.currencyCode: 'CurrencyCode'
Booking.price as Price,
Booking.currency_code as CurrencyCode,
Booking.booking_status as BookingStatus,
" Assoziationen exponieren
_Flight,
_Customer
}

Kardinalitäten

KardinalitätBedeutungBeispiel
[0..1]Optional, max. 1Optionaler Ansprechpartner
[1..1]Genau 1Buchung → Flug
[0..*]Optional, beliebig vieleKunde → Buchungen
[1..*]Mindestens 1, beliebig vieleBestellung → Positionen

Tabellen befüllen und lesen

Daten einfügen

" Einzelner Datensatz
INSERT INTO zflight_book VALUES @(
VALUE #(
client = sy-mandt
booking_id = '0000000001'
flight_id = '0000000100'
customer_id = '0000000001'
booking_date = cl_abap_context_info=>get_system_date( )
price = '499.00'
currency_code = 'EUR'
booking_status = 'O'
created_by = cl_abap_context_info=>get_user_technical_name( )
created_at = utclong_current( )
)
).
" Mehrere Datensätze
DATA(lt_bookings) = VALUE #(
( client = sy-mandt booking_id = '0000000002' flight_id = '0000000101' ... )
( client = sy-mandt booking_id = '0000000003' flight_id = '0000000102' ... )
).
INSERT zflight_book FROM TABLE @lt_bookings.

Daten lesen

" Über CDS View lesen (empfohlen für RAP)
SELECT FROM ZI_FlightBooking
FIELDS BookingId, FlightId, BookingDate, Price
WHERE BookingStatus = 'O'
INTO TABLE @DATA(lt_open_bookings).
" Mit Assoziationen
SELECT FROM ZI_FlightBooking AS Booking
FIELDS Booking~BookingId,
\_Flight-DepartureCity,
\_Flight-ArrivalCity,
\_Customer-LastName
INTO TABLE @DATA(lt_with_details).

Best Practices

1. Administrative Felder immer einplanen

" Diese Felder sollte jede Tabelle haben:
created_by : abap.uname;
created_at : abap.utclong;
last_changed_by : abap.uname;
last_changed_at : abap.utclong;
local_last_changed: abap.utclong; " Für ETag/Optimistic Locking

2. Semantische Annotationen nutzen

" Währungsfelder korrekt annotieren
@Semantics.amount.currencyCode: 'currency_code'
price : abap.curr(15,2);
currency_code : abap.cuky;
" Mengenfelder korrekt annotieren
@Semantics.quantity.unitOfMeasure: 'unit'
quantity : abap.quan(13,3);
unit : abap.unit(3);

3. Namenskonventionen einhalten

Tabellen: z<bereich>_<name> → zflight_book
Table Entities: zi_<name> → zi_flightbooking
CDS Views: ZI_<Name> (Interface) → ZI_FlightBooking
ZC_<Name> (Consumption) → ZC_FlightBooking

4. UTCLONG statt DATS/TIMS

" ❌ Vermeiden:
changed_date : abap.dats;
changed_time : abap.tims;
" ✅ Bevorzugen:
changed_at : abap.utclong;

Fazit

Tabellen in ABAP Cloud werden ausschließlich über DDL Source in ADT definiert:

Klassisch (SE11)ABAP Cloud (ADT)
GUI-basiertCode-basiert
Domäne → Datenelement → TabelleTypen inline oder als Type
Foreign Key DialogForeign Key Annotation
Nicht versionierbarGit-ready

Die Umstellung erfordert anfangs Einarbeitung, bietet aber klare Vorteile: Bessere Lesbarkeit, Versionskontrolle und Integration mit dem RAP-Stack.

Für die nächsten Schritte mit RAP siehe RAP Grundlagen, für CDS Views im Detail CDS Views und für die Migration bestehender Objekte den ABAP Cloud Migration Guide.