Open SQL
ABAP Developmentadvanced

Open SQL Part 10: Open SQL in Real Reports and Interfaces

Key takeaway

Put it all together: a complete classic report and an interface extract with selection screen, authorization, efficient reads, joins, FOR ALL ENTRIES, totals, locking-aware updates and a review checklist.

Explanation

📌 KEY POINTS
✅ Real programs follow one flow: selection → authorization → read (few statements) → process in memory → output/update.

✅ Changing data: INSERT/UPDATE/MODIFY … FROM TABLE for mass changes, with lock objects and COMMIT WORK.

✅ Custom tables only — standard SAP data is changed via BAPIs/APIs, never directly.

💡 Review every program with the checklist below before transport.

━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE

Parts 1–9 covered the tools. This final part builds a realistic flight occupancy report and a booking extract for an external system.

━━━━━━━━━━━━━━━━━━━━
▶ 1. THE READ FLOW

  • Selection screen with ranges and validation (ABAP Core Part 5).
  • AUTHORITY-CHECK on organizational values (airline) before reading.
  • Read header data with field lists and WHERE conditions.
  • Read dependent data once: JOIN or FAE (with emptiness check and de-duplication).
  • Lookup tables (master data) into HASHED tables.
  • Process in memory with sorted/hashed tables — no SQL in loops.
  • Output via ALV (ALV topic) or file.

━━━━━━━━━━━━━━━━━━━━
▶ 2. WRITING DATA — CUSTOM TABLES ONLY

  • INSERT ztab FROM TABLE gt_new. — mass insert; duplicates raise an exception or sy-subrc 4 (with ACCEPTING DUPLICATE KEYS).
  • UPDATE ztab FROM TABLE gt_changed. — by primary key.
  • MODIFY ztab FROM TABLE gt_rows. — insert or update.
  • DELETE ztab FROM TABLE gt_del. / DELETE FROM ztab WHERE ….
  • Protect concurrent changes with lock objects (ENQUEUE_/DEQUEUE_ function modules generated in SE11).
  • COMMIT WORK at a consistent point; ROLLBACK WORK on error.

⚠️ Never update SAP standard tables directly — use BAPIs or released APIs (BAPI topic).

━━━━━━━━━━━━━━━━━━━━
▶ 3. INTERFACE EXTRACTS

  • Delta selection by change date/time stamp.
  • Package processing for large volumes (Part 7).
  • Conversion exits (ALPHA) and currency/unit formatting for external formats.
  • Log what was extracted (counts, keys) in the application log.

━━━━━━━━━━━━━━━━━━━━
▶ 4. REVIEW CHECKLIST

□ No SELECT * without reason □ All filters in WHERE □ No SELECT in loops □ FAE: not empty, de-duplicated, full keys □ SELECT SINGLE only with full key □ Aggregation in SQL □ Currency grouped □ Hashed/sorted lookup tables □ Package processing for mass data □ Authorization checks □ Locks + commit handling for updates □ ST05 trace done with realistic data.

━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP

Run the code example: occupancy report with totals, then the extract writing into a custom status table ZFLIGHT_EXTR (create it in SE11 with key MANDT, CARRID, CONNID, FLDATE and fields EXTRACTED_ON, BOOKINGS).

✅ CHECKPOINT: you can build and review a complete SQL-based program. Open SQL complete — next topic: Modularization.

Code example

ABAP Code
REPORT zosql_part10. TABLES sflight.SELECT-OPTIONS s_carr FOR sflight-carrid OBLIGATORY.SELECT-OPTIONS s_date FOR sflight-fldate.PARAMETERS p_extr AS CHECKBOX.                     " write extract table? TYPES: BEGIN OF ty_out,         carrid   TYPE s_carr_id,         carrname TYPE s_carrname,         connid   TYPE s_conn_id,         fldate   TYPE s_date,         seatsocc TYPE s_seatsocc,         seatsmax TYPE s_seatsmax,         bookings TYPE i,       END OF ty_out,       BEGIN OF ty_cnt,         carrid   TYPE s_carr_id,         connid   TYPE s_conn_id,         fldate   TYPE s_date,         bookings TYPE i,       END OF ty_cnt. DATA: gt_out   TYPE STANDARD TABLE OF ty_out,      gs_out   TYPE ty_out,      gt_cnt   TYPE SORTED TABLE OF ty_cnt WITH UNIQUE KEY carrid connid fldate,      gs_cnt   TYPE ty_cnt,      gt_carr  TYPE HASHED TABLE OF scarr WITH UNIQUE KEY carrid,      gs_carr  TYPE scarr,      gt_extr  TYPE STANDARD TABLE OF zflight_extr,     " custom table (SE11)      gs_extr  TYPE zflight_extr,      gs_range LIKE LINE OF s_carr. FIELD-SYMBOLS <ls_out> TYPE ty_out. AT SELECTION-SCREEN.  LOOP AT s_carr INTO gs_range WHERE option = 'EQ'.    AUTHORITY-CHECK OBJECT 'S_CARRID' ID 'CARRID' FIELD gs_range-low ID 'ACTVT' FIELD '03'.    IF sy-subrc <> 0.      MESSAGE e002(zflight) WITH gs_range-low.    ENDIF.  ENDLOOP. START-OF-SELECTION.* ===== 1. lookup table (small, buffered) =====  SELECT * FROM scarr INTO TABLE gt_carr WHERE carrid IN s_carr. * ===== 2. flights, then booking counts aggregated in the database =====  SELECT carrid connid fldate seatsocc seatsmax    FROM sflight    INTO CORRESPONDING FIELDS OF TABLE gt_out    WHERE carrid IN s_carr      AND fldate IN s_date.   SELECT carrid connid fldate COUNT( * )    FROM sbook    INTO TABLE gt_cnt    WHERE carrid IN s_carr      AND fldate IN s_date      AND cancelled = space    GROUP BY carrid connid fldate. * ===== 3. enrich in memory (hashed/sorted lookup, no SQL in loop) =====  LOOP AT gt_out ASSIGNING <ls_out>.    READ TABLE gt_carr INTO gs_carr WITH TABLE KEY carrid = <ls_out>-carrid.    IF sy-subrc = 0.      <ls_out>-carrname = gs_carr-carrname.    ENDIF.    READ TABLE gt_cnt INTO gs_cnt WITH TABLE KEY carrid = <ls_out>-carrid                                                 connid = <ls_out>-connid                                                 fldate = <ls_out>-fldate.    IF sy-subrc = 0.      <ls_out>-bookings = gs_cnt-bookings.    ENDIF.  ENDLOOP.   LOOP AT gt_out INTO gs_out.                      " real reports: ALV    WRITE: / gs_out-carrid, gs_out-carrname, gs_out-connid, gs_out-fldate, gs_out-bookings.  ENDLOOP. * ===== 4. write extract into a CUSTOM table (mass DML + commit) =====  IF p_extr = 'X' AND gt_out IS NOT INITIAL.    LOOP AT gt_out INTO gs_out.      CLEAR gs_extr.      gs_extr-carrid       = gs_out-carrid.      gs_extr-connid       = gs_out-connid.      gs_extr-fldate       = gs_out-fldate.      gs_extr-extracted_on = sy-datum.      gs_extr-bookings     = gs_out-bookings.      APPEND gs_extr TO gt_extr.    ENDLOOP.    MODIFY zflight_extr FROM TABLE gt_extr.        " insert or update by key    IF sy-subrc = 0.      COMMIT WORK.    ELSE.      ROLLBACK WORK.    ENDIF.  ENDIF. * 💡 Strict syntax (7.50) can do the join + COUNT in one statement:*    SELECT f~carrid, ..., COUNT( b~bookid ) AS bookings FROM sflight AS f*      LEFT OUTER JOIN sbook AS b ON ... GROUP BY ... INTO TABLE @gt_out.

Real project scenario

A new team member built an interface extract that selected headers, then items in a loop, then updated a custom log table with one UPDATE per item and a COMMIT after each. It worked in development and took four hours in production, creating thousands of tiny database transactions.
Using the review checklist, the team rewrote it as a join with aggregation, FAE for the external key list, a hashed master-data table, and one MODIFY FROM TABLE per package with a commit per package. Runtime dropped to eight minutes; the checklist became part of the team's definition of done.

Common mistakes

  • SQL inside loops for reads or writes.
  • Direct updates of SAP standard tables.
  • One COMMIT per row or no commit strategy at all.
  • No authorization check for selected organizational values.
  • No lock handling for custom tables changed by several users/jobs.

Best practices

  • Selection → authorization → bulk read → memory processing → output/mass update.
  • Mass DML with FROM TABLE; commit at consistent points.
  • Lock objects for custom tables with concurrent changes.
  • BAPIs/APIs for SAP standard data.
  • Apply the SQL review checklist and trace before transport.

Interview angle

Questions: "How do you structure a performant report?", "How do you update custom tables efficiently?", "May you update SAP standard tables directly?"
Strong answer: select with filters and field lists after authorization checks, read related data in bulk (JOIN/FAE), use hashed lookup tables, process in memory, output via ALV; update custom tables with INSERT/UPDATE/MODIFY … FROM TABLE, lock objects and COMMIT/ROLLBACK at consistent points; never modify SAP standard tables directly — use BAPIs/released APIs.

Practice this lesson

Quick check

1. How should a program change rows of a custom table for 10,000 records?

2. How should an ABAP program change SAP standard application data (e.g. sales orders)?

3. Which statement performs an upsert in Open SQL (7.40+)?

Interview questions

1. A concurrent update is producing occasional data loss on a Z table. How do you detect and prevent it in Open SQL / ABAP?

Answer it in your own words first, then compare.

2. An OData service reuses SQL from an internal report. What must you check?

Answer it in your own words first, then compare.

Practice more with Interview AI →

Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.

More lessons in this topic

Interview questions on this topic

Related SAP topics