ABAP SQL & CDS-views
Data lezen en schrijven met ABAP SQL (Open SQL): SELECT in alle varianten, joins, aggregaties, FOR ALL ENTRIES, moderne expressies in SQL, en CDS-views als moderne datamodellen.
01SELECT: data lezen
ABAP SQL (voorheen Open SQL) is SAP's database-onafhankelijke SQL-dialect, direct in de taal ingebouwd. De moderne schrijfwijze gebruikt komma's tussen velden en een @ voor ABAP-variabelen ("host variables").
" Meerdere rijen in een interne tabel
SELECT matnr, mtart, matkl
FROM mara
WHERE mtart = @lv_mtart
AND matnr IN @s_matnr
INTO TABLE @DATA(lt_mara)
UP TO 100 ROWS.
" Eén rij
SELECT SINGLE matnr, mtart
FROM mara
WHERE matnr = @lv_matnr
INTO @DATA(ls_mara).
IF sy-subrc <> 0.
" niets gevonden — ALTIJD checken
ENDIF.
sy-subrc= 0 als er iets gevonden is, 4 als niet;sy-dbcnt= aantal gelezen rijen.SELECT ... ENDSELECT(rij-voor-rij-lus) bestaat, maar haal liever alles in één keer op metINTO TABLE— elke lusronde is een database-rondgang.SELECT *alleen als je echt alle velden nodig hebt; expliciete veldlijsten zijn sneller en HANA-vriendelijker.- Oude syntax zonder komma's en
@(SELECT matnr mtart FROM mara INTO TABLE lt_mara) kom je overal tegen; betekenis is gelijk. ORDER BY: databases geven zónder ORDER BY geen gegarandeerde volgorde — op HANA merk je dat direct. Sorteer in SQL (ORDER BY PRIMARY KEYof veldlijst) of daarna met SORT.
Aggregatie & groepering
SELECT matkl, COUNT( * ) AS aantal, SUM( ntgew ) AS gewicht
FROM mara
GROUP BY matkl
HAVING COUNT( * ) > 10
ORDER BY aantal DESCENDING
INTO TABLE @DATA(lt_stats).
Beschikbaar: COUNT, SUM, AVG, MIN, MAX, en SELECT DISTINCT voor unieke rijen.
02Joins, FOR ALL ENTRIES & subqueries
Tabellen combineren — en het beruchte alternatief wanneer één van de "tabellen" een interne tabel is.
Joins
SELECT k~vbeln, k~erdat, p~posnr, p~matnr, p~netwr
FROM vbak AS k
INNER JOIN vbap AS p
ON p~vbeln = k~vbeln
LEFT OUTER JOIN makt AS t
ON t~matnr = p~matnr
AND t~spras = @sy-langu
WHERE k~erdat >= @lv_van
INTO TABLE @DATA(lt_result).
Tabel-alias met ~ voor veldtoegang. INNER JOIN: alleen rijen die aan beide kanten bestaan; LEFT OUTER JOIN: alle linkerrijen, rechts leeg indien geen match. Ook beschikbaar: RIGHT OUTER JOIN, CROSS JOIN, en UNION/UNION ALL.
FOR ALL ENTRIES
Wil je databasedata ophalen voor de inhoud van een interne tabel, dan is er FOR ALL ENTRIES:
IF lt_orders IS NOT INITIAL. " ← ABSOLUUT VERPLICHT
SELECT matnr, maktx
FROM makt
FOR ALL ENTRIES IN @lt_orders
WHERE matnr = @lt_orders-matnr
AND spras = @sy-langu
INTO TABLE @DATA(lt_teksten).
ENDIF.
Subqueries
SELECT matnr FROM mara
WHERE EXISTS ( SELECT matnr FROM marc
WHERE matnr = mara~matnr AND werks = @p_werk )
INTO TABLE @DATA(lt_matnr).
03Moderne SQL-expressies
Sinds 7.40/7.50 kan er steeds meer ín het SQL-statement — berekend op de database in plaats van in ABAP (zie code pushdown).
SELECT vbeln,
netwr * @lv_koers AS netwr_eur, " rekenexpressie
CASE WHEN netwr > 10000 THEN 'A'
ELSE 'B' END AS klasse, " CASE
CONCAT( vbeln, posnr ) AS sleutel, " stringfuncties
COALESCE( t~maktx, '(geen tekst)' ) AS tekst " NULL-afhandeling
FROM vbap ...
- Beschikbaar o.a.:
CASE, rekenkundige expressies,CAST, string- en datumfuncties (CONCAT,LEFT,DATS_ADD_DAYS…),COALESCE. - CTE's (Common Table Expressions) met
WITH +naam AS ( SELECT ... )— leesbaar alternatief voor geneste subqueries en FOR ALL ENTRIES. - Window-functies (
OVER ( PARTITION BY ... )) op nieuwere releases. SELECT ... FROM @lt_itab: op recente releases kun je zelfs een interne tabel als bron gebruiken.
04Schrijven: INSERT, UPDATE, MODIFY, DELETE
Rechtstreeks schrijven doe je alleen op eigen Z-tabellen. SAP-standaardtabellen wijzig je vrijwel altijd via BAPI's — die bewaken de consistentie over alle gerelateerde tabellen.
INSERT ztabel FROM @ls_regel. " sy-subrc 4 als key al bestaat
INSERT ztabel FROM TABLE @lt_regels.
UPDATE ztabel FROM @ls_regel. " sy-subrc 4 als key niet bestaat
UPDATE ztabel SET status = 'X' WHERE erdat < @lv_datum.
MODIFY ztabel FROM @ls_regel. " INSERT als nieuw, anders UPDATE
DELETE FROM ztabel WHERE status = 'X'.
Wijzigingen zijn pas definitief na COMMIT WORK; tot die tijd kan ROLLBACK WORK alles terugdraaien. Beveilig gelijktijdige toegang met locks.
05CDS-views
Core Data Services: datamodellen als broncode, met semantiek die verder gaat dan een klassieke database-view. Dé modelleerlaag van S/4HANA.
" Definitie in ADT (Eclipse), bestandstype "data definition"
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Verkooporders met klant'
define view entity ZI_SalesOrder
as select from vbak
association [0..1] to kna1 as _Klant
on $projection.kunnr = _Klant.kunnr
{
key vbak.vbeln,
vbak.erdat,
vbak.kunnr,
@Semantics.amount.currencyCode: 'waerk'
vbak.netwr,
vbak.waerk,
_Klant // associatie mee-exposen
}
- Annotaties (
@...) voegen semantiek toe: valuta/eenheid-koppeling, UI-labels, zoekgedrag, autorisatie, OData-publicatie. - Associaties zijn "joins on demand": ze worden pas uitgevoerd als een consument het gekoppelde pad echt opvraagt (
_Klant.name1). - Access control (DCL): autorisaties declaratief op de view, gekoppeld aan autorisatie-objecten.
- Views zijn stapelbaar: interface-views (
ZI_...) op de tabellen, consumption-views (ZC_...) daarbovenop voor apps/analytics — het "Virtual Data Model" (VDM) van S/4HANA. - In ABAP lees je een CDS-view als elke andere bron:
SELECT ... FROM zi_salesorder. - De oudere vorm
define view(met aparte SQL-viewnaam) is opgevolgd doordefine view entity.
CDS is ook de basis van RAP en van embedded analytics. Meer diepgang op de moderne-ABAP-pagina.
06SQL-performance: de gouden regels
De vijf klassieke regels — plus wat er op HANA verandert.
- Houd de resultaatset klein — filter met WHERE op de database, niet achteraf in ABAP.
- Verstuur weinig data — veldlijst i.p.v.
SELECT *, aggregaties op de database. - Beperk het aantal rondgangen — geen SELECT in een LOOP (het klassieke "N+1"-probleem); gebruik joins, FOR ALL ENTRIES of één ophaling vooraf in een hashed tabel.
- Gebruik indexen — laat de WHERE aansluiten op de primaire sleutel of een (secundaire) index; velden waarop je met
LIKE '%..'of NOT filtert gebruiken de index niet. - Ontlast de database waar mogelijk — gebufferde tabellen (klein & stabiel, zie technische instellingen) niet omzeilen met
BYPASSING BUFFERzonder reden.
Op HANA verschuift regel 5: reken- en aggregatiewerk mag juist wél naar de database (code pushdown), terwijl regels 1–4 onverminderd gelden. Meetgereedschap: SQL-trace (ST05) en runtime-analyse.