Internal Tables
ABAP Developmentbeginner

Internal Tables Part 1: Standard, Sorted and Hashed Tables

Key takeaway

Understand internal tables from the ground up: what they are, the line type and the table key, the three table kinds (standard, sorted, hashed), work areas, and filling and reading a table from SFLIGHT in a classic report.

What this complete series covers

Learn Internal Tables in a clear, practical sequence — from the basic idea to real project use, troubleshooting, and interview-ready understanding.

Who it is for
Best for SAP consultants, developers, and learners who want a practical understanding of Internal Tables.
Prerequisites
Basic SAP navigation and ABAP syntax help. For hands-on practice, use an ABAP system with ADT or the relevant ABAP development tools.
Final outcome
By the end, you should be able to explain Internal Tables clearly, follow the main end-to-end flow, apply it in a project scenario, and troubleshoot the most common issues.
  1. Part 1: Internal Tables Part 1: Standard, Sorted and Hashed Tables

    Standard, Sorted, Hashed tables, secondary keys, and how to pick the right one so your reports scale.

  2. Part 2: Internal Tables Part 2: Choosing the Right Table Type

    Choose STANDARD, SORTED or HASHED internal tables from the dominant access pattern, uniqueness and ordering requirements, and use secondary keys when one dataset needs multiple efficient lookup paths.

  3. Part 3: Internal Tables Part 3: Work Area vs Field Symbol vs Data Reference

    Choose work areas, field symbols and data references from ownership and lifetime needs: work areas copy rows, field symbols alias existing memory and references provide explicit ob

  4. Part 4: Internal Tables Part 4: READ TABLE, sy-subrc and Table Expressions

    Choose READ TABLE, lineexists and table expressions according to whether you need existence, row data or exception behavior, and always use a key that matches the internal-table design.

  5. Part 5: Internal Tables Part 5: SORT, BINARY SEARCH and Secondary Keys

    Use BINARY SEARCH only on a correctly sorted compatible key, and prefer SORTED or secondary-key table definitions when the access pattern is repeated enough that the data structure

  6. Part 6: Internal Tables Part 6: APPEND, INSERT, MODIFY, DELETE and COLLECT

    Use internal-table modification statements according to table type and intent, understanding index versus key behavior, in-place field-symbol updates and the special aggregation semantics of COLLECT.

  7. Part 7: Internal Tables Part 7: Removing Duplicates and Building Unique Datasets

    Build unique driver datasets with keyed internal tables or deliberate sort-and-delete logic so downstream SQL and processing do not repeat the same business key unnecessarily.

  8. Part 8: Internal Tables Part 8: LOOP Patterns — WHERE, Control Levels and Totals

    Choose modern ABAP looping and constructor expressions for clarity: use ASSIGNING for in-place row work, WHERE or GROUP BY for focused iteration, and VALUE, FILTER or REDUCE when e

  9. Part 9: Internal Tables Part 9: Nested LOOP Optimization and Parallel Cursor

    Replace expensive nested-loop scans with keyed internal tables, grouped iteration or range-based access; use classic parallel-cursor logic only when it remains clearer than modern

  10. Part 10: Internal Tables Part 10: Memory Management and Large Internal Tables

    Control ABAP memory by reducing data at the database, avoiding duplicate full-table copies, processing large volumes in packages and releasing genuinely large temporary datasets wh

System and release assumptions: Examples follow modern ABAP practices. Exact syntax, available APIs, and tools can vary by SAP release, so release-dependent points are called out where needed.

Explanation

📌 KEY POINTS
✅ An internal table is a temporary, in-memory table in your program — it lives only while the program runs.

✅ It is defined by a line type (structure), a table kind (STANDARD, SORTED, HASHED) and a key.

✅ Classic processing uses a work area: read a row into it, change it, write it back.

⚠️ Never use tables WITH HEADER LINE or OCCURS in new code — they are obsolete and confusing.

━━━━━━━━━━━━━━━━━━━━
▶ WHAT THIS SERIES COVERS

  • Part 1 — table kinds and basics (this lesson)
  • Part 2 — choosing the right table kind
  • Part 3 — work area vs field symbol vs data reference
  • Part 4 — READ TABLE and sy-subrc
  • Part 5 — SORT, BINARY SEARCH and secondary keys
  • Part 6 — APPEND, INSERT, MODIFY, DELETE, COLLECT
  • Part 7 — removing duplicates
  • Part 8 — LOOP patterns and control levels
  • Part 9 — nested loops and parallel cursor
  • Part 10 — memory and large tables

━━━━━━━━━━━━━━━━━━━━
▶ 1. WHAT AN INTERNAL TABLE IS

Almost every ABAP program reads data from the database into internal tables, processes it in memory, and outputs or saves the result. Think of it as an array of structures: every row has the same columns (the line type).

━━━━━━━━━━━━━━━━━━━━
▶ 2. THE THREE PARTS OF A DEFINITION

  • Line type — usually a dictionary table/structure (SFLIGHT) or a local TYPES structure.
  • Table kind — STANDARD, SORTED or HASHED.
  • Key — the fields that identify a row (UNIQUE or NON-UNIQUE).

━━━━━━━━━━━━━━━━━━━━
▶ 3. THE THREE TABLE KINDS

  • STANDARD TABLE — rows in insertion order, accessed by index or by key with a linear search (slow on large tables unless sorted + BINARY SEARCH). The most common kind in classic code.
  • SORTED TABLE — always kept sorted by its key; key access uses a binary search automatically. Key can be UNIQUE or NON-UNIQUE.
  • HASHED TABLE — access only by the full unique key via a hash function; constant access time regardless of size; no index access.

━━━━━━━━━━━━━━━━━━━━
▶ 4. CLASSIC DECLARATION WITH A WORK AREA

TYPES: BEGIN OF ty_flight, carrid TYPE s_carr_id, connid TYPE s_conn_id, fldate TYPE s_date, seatsocc TYPE s_seatsocc, END OF ty_flight.

DATA: gt_flights TYPE STANDARD TABLE OF ty_flight,

gs_flight TYPE ty_flight.

The work area gs_flight holds one row at a time.

━━━━━━━━━━━━━━━━━━━━
▶ 5. FILL, READ, LOOP

  • Fill from the database: SELECT … INTO TABLE gt_flights.
  • Add a row: APPEND gs_flight TO gt_flights.
  • Read one row: READ TABLE gt_flights INTO gs_flight WITH KEY connid = '0400'.
  • Process all rows: LOOP AT gt_flights INTO gs_flight. … ENDLOOP.
  • Count rows: DESCRIBE TABLE gt_flights LINES lv_lines. (💡 Modern: lines( gt_flights ).)

━━━━━━━━━━━━━━━━━━━━
▶ 6. HEADER LINES — WHY NOT

Old code declares DATA itab TYPE … WITH HEADER LINE or OCCURS 0 — the table and a work area with the same name. It is ambiguous (itab vs itab[]) and not allowed in classes. You must read it in legacy code, but never write it.

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

  1. Create report ZITAB_BASICS with the code example.
  2. Run it for airline LH; see the row count and the loop output.
  3. Change the READ key to a connection that does not exist and check sy-subrc = 4.

💡 Modern syntax (7.40+): SELECT … INTO TABLE @DATA(lt_flights), LOOP AT … INTO DATA(ls_flight), lines( ).

✅ CHECKPOINT: you can declare, fill, read and loop over an internal table with a work area.

Code example

ABAP Code
REPORT zitab_basics. * ===== Step 1: line type, table and work area (classic style) =====TYPES: BEGIN OF ty_flight,         carrid   TYPE s_carr_id,         connid   TYPE s_conn_id,         fldate   TYPE s_date,         seatsmax TYPE s_seatsmax,         seatsocc TYPE s_seatsocc,       END OF ty_flight. DATA: gt_flights TYPE STANDARD TABLE OF ty_flight,        " standard table      gs_flight  TYPE ty_flight,                           " work area      gv_lines   TYPE i. PARAMETERS p_carr TYPE s_carr_id DEFAULT 'LH'. START-OF-SELECTION.* ===== Step 2: fill the table from the database =====  SELECT carrid connid fldate seatsmax seatsocc    FROM sflight    INTO TABLE gt_flights    WHERE carrid = p_carr.   IF sy-subrc <> 0.    WRITE: / 'No flights found for', p_carr.    STOP.  ENDIF.   DESCRIBE TABLE gt_flights LINES gv_lines.  WRITE: / 'Number of flights:', gv_lines. * ===== Step 3: read one row by key =====  READ TABLE gt_flights INTO gs_flight WITH KEY connid = '0400'.  IF sy-subrc = 0.    WRITE: / 'First flight of 0400 on', gs_flight-fldate.  ELSE.    WRITE: / 'Connection 0400 not in table'.  ENDIF. * ===== Step 4: add a row manually =====  CLEAR gs_flight.  gs_flight-carrid = p_carr.  gs_flight-connid = '9999'.  gs_flight-fldate = sy-datum.  APPEND gs_flight TO gt_flights. * ===== Step 5: process all rows =====  ULINE.  LOOP AT gt_flights INTO gs_flight.    WRITE: / sy-tabix, gs_flight-carrid, gs_flight-connid, gs_flight-fldate,             gs_flight-seatsocc, '/', gs_flight-seatsmax.  ENDLOOP. * ===== Other table kinds (declarations) =====DATA: gt_sorted TYPE SORTED TABLE OF ty_flight                WITH NON-UNIQUE KEY carrid connid fldate,      gt_hashed TYPE HASHED TABLE OF ty_flight                WITH UNIQUE KEY carrid connid fldate. * ===== OBSOLETE - only read it in legacy code =====* DATA itab TYPE ty_flight OCCURS 0 WITH HEADER LINE.

Real project scenario

A support developer changed a legacy report where an internal table was declared WITH HEADER LINE. He wrote CLEAR itab to empty the table, but that only cleared the header line; the table kept old rows and the next run of the loop produced duplicate records in an output file.
The team fixed it with CLEAR itab[] and, in the next change, replaced the header line with an explicit work area. They added "no header lines in new code" to their review checklist.

Common mistakes

  • Declaring new tables WITH HEADER LINE or OCCURS.
  • Confusing itab and itab[] in legacy code.
  • Not checking sy-subrc after READ TABLE.
  • Forgetting CLEAR on the work area before filling a new row.
  • Using a standard table for large key lookups without sorting.

Best practices

  • Use explicit work areas (or field symbols) and no header lines.
  • Base line types on dictionary structures or clear local TYPES.
  • Choose the table kind based on access pattern (Part 2).
  • Always check sy-subrc after READ.
  • Keep tables local to the processing that needs them.

Interview angle

Questions: "What is an internal table?", "Difference between standard, sorted and hashed tables?", "Why avoid header lines?"
Strong answer: an internal table is an in-memory table defined by line type, table kind and key; standard tables keep insertion order with index access and linear key search, sorted tables keep key order with automatic binary search, hashed tables allow only unique-key access with constant time; header lines are obsolete, ambiguous (itab vs itab[]) and not allowed in OO contexts.

Practice this lesson

Quick check

1. Why should header lines (OCCURS 0 WITH HEADER LINE) be avoided?

2. Which statement adds a row to a STANDARD table at the end?

3. If an internal table type is declared simply as "DATA itab TYPE TABLE OF ty_line." without specifying STANDARD, SORTED, or HASHED, which table category is used by default?

Interview questions

1. What are the three types of internal tables in ABAP (Standard, Sorted, Hashed) and how do they differ in terms of key definition and access?

Answer it in your own words first, then compare.

2. What is the difference between STANDARD, SORTED, and HASHED internal tables?

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