Lesson 5 of 6
Modern ABAP SQL
11 min
Listen to this lesson
Open SQL is now called ABAP SQL, and its syntax changed as much as the rest of the language. Since ABAP 7.40, host variables are escaped with @, field lists are separated by commas, the INTO clause can come last with an inline declaration, and SQL expressions (arithmetic, CASE, string functions, COALESCE) push work to SAP HANA. In ABAP Cloud, the other half of the change is what you select from: released CDS views instead of tables.
Classic and modern, side by side
| Feature | Classic | Modern |
|---|---|---|
| Field list | SELECT id customer status FROM zcmc_core_agr | SELECT id, customer, status FROM zcmc_core_agr |
| Host variables | WHERE customer = lv_customer | WHERE customer = @customer |
| Target | INTO TABLE lt_agr | INTO TABLE @DATA(agreements) |
| Clause order | INTO before WHERE | FIELDS and INTO after WHERE and ORDER BY, so the statement reads in order |
| Calculations | LOOP after the select | CASE status WHEN 'OPEN' THEN 'Active' ELSE 'Ended' END AS status_text |
| Expressions as operands | Helper variable first | WHERE valid_to >= @( cl_abap_context_info=>get_system_date( ) ) |
| Null handling | LOOP and IF | COALESCE( total_deposit, 0 ) AS total |
Modern ABAP SQL compared with the classic form, using Contoso's agreement table.
Strict mode
ABAP SQL has strict modes of the syntax check. As soon as a statement uses a newer syntax element, such as @ escaping or a comma-separated list, the statement is checked in strict mode and must follow the new rules throughout: all host variables escaped with @, comma-separated lists, and other rules the keyword documentation lists per release. That is why a half-converted statement fails to compile: you cannot mix @customer and an unescaped lv_status in one statement. Convert a statement completely or not at all.
Selecting from released CDS views
In ABAP for Cloud Development, a SELECT on KNA1 or MARA is not allowed: those tables are not released. You read the released CDS views instead, such as I_Customer for customers. Your own tables (like ZCMC_CORE_AGR) in the same software component are allowed. The modern SQL syntax and the released views come together: a join of ZCMC_CORE_AGR with I_Customer on the customer number gives the agreement list with customer names in one statement, which replaces the classic pattern of a SELECT loop with a SELECT SINGLE per row. Check each view's release state in ADT (the API state in the Properties view) before using it.
Two more modern habits matter for correctness, not just style. First, name the fields you need instead of SELECT *: the CDS view or table may gain fields after an upgrade, and the code should not change behavior because of it. Second, when only one row is wanted and the key is not complete, write SELECT ... ORDER BY ... INTO @DATA(row) UP TO 1 ROWS and say which row you mean. Both make the statement's result deterministic, which is what a test needs to assert it.
Walkthrough: one legacy select
- Legacy:
SELECT * FROM zcmc_core_agr INTO TABLE lt_agr WHERE status = lv_status.thenLOOPwithSELECT SINGLE name1 FROM kna1per row. - Write a characterization test with the ABAP SQL test double framework: insert three agreements (two OPEN for 17100001, one CLOSED) and the customer data the code reads, and pin the output.
- Replace
SELECT *with the fields actually used. - Join
I_Customerfor the name, escape host variables, moveINTO TABLE @DATA(agreements)to the end. - Add the status text with a
CASEexpression instead of the loop. - Update the test's doubles to the new data sources and confirm the output is unchanged.
- Step 1PinCharacterization test with SQL test doubles
- Step 2NarrowNamed fields instead of SELECT *
- Step 3ModernizeComma lists, @ escapes, INTO at the end
- Step 4Push downJoin I_Customer, CASE expression for status text
- Step 5ProveSame output, fewer round trips, tests green
What goes wrong in testing
- FOR ALL ENTRIES with an empty driver table. It reads every row of the table, in modern syntax as in classic. Check the table is not initial, or use a join.
- SELECT SINGLE without the full key. The row returned is not defined. Use the full key, or
UP TO 1 ROWSwithORDER BY. - CDS view semantics. A released view may filter, convert or add fields differently from the table it replaces. Compare output on realistic data, not only on the happy path.
- Client and authorization. CDS views can carry access control. A user may see fewer rows than the old table select returned; test with real roles in CMQ.
What would you do?
Kenji converts a select to modern syntax and it fails to compile with an error about host variables. The statement uses @customer in the WHERE clause and lv_status in another condition. What is the cause?
- Modern ABAP SQL: comma lists, @ host variables, INTO at the end with inline declarations, SQL expressions.
- Any new element puts the statement in strict mode; convert the whole statement.
- In ABAP Cloud, select from released CDS views such as I_Customer, not SAP tables.
- Pin output with SQL test doubles before refactoring, and compare on realistic data after.
Check your understanding · not graded
Lesson check
1. How are host variables written in modern ABAP SQL?
2. What switches a SELECT statement into strict mode?
3. What should ABAP Cloud code read instead of KNA1?
4. What does FOR ALL ENTRIES do with an empty driver table?
5. Why compare output on realistic data after replacing a table with a CDS view?