Learn SAP Free
Back to Dashboard
ABAP Programming

Field Symbols in ABAP – Dynamic Data Access Explained for Beginners

Daksh | July 24, 2026 | 9 min read

Field Symbols in ABAP

If you have been writing ABAP programs using LOOP AT with INTO, you are doing it the traditional way — and it works perfectly fine for small datasets. But as your internal tables grow to thousands or millions of rows, you will notice that performance becomes an issue.

The reason is simple. When you use LOOP AT lt_table INTO ls_workarea, ABAP copies the entire row from the table into the work area. That is a full copy operation for every single row. If your table has 100,000 rows with 50 fields each, that is 100,000 copy operations. It eats up memory and slows down your program.

Field Symbols solve this problem. Instead of copying the data, a Field Symbol points directly to the row in the internal table. No copy, no extra memory. You work directly with the original data in place. Think of it like a shortcut on your desktop — the shortcut is not a copy of the file, it just points to where the file actually is.

In this tutorial, we will learn what Field Symbols are, how to declare and use them, and why they are the preferred way to loop through internal tables in modern ABAP.


What is a Field Symbol?

A Field Symbol is a placeholder that points to an existing variable or a row in memory. It does not have its own storage space. Instead, it refers to (points to) another piece of data.

When you assign a variable to a Field Symbol, any change you make through the Field Symbol directly changes the original variable. There is no intermediate copy.

Key Properties:

  • Field Symbols do not allocate their own memory
  • They point to existing data objects
  • Changes through a Field Symbol affect the original data
  • They are declared using angle brackets: <fs_name>
  • They must be assigned to a data object before use

Basic Syntax

Declaring a Field Symbol

FIELD-SYMBOLS: <fs_name> TYPE data_type.

Assigning a Variable to a Field Symbol

ASSIGN lv_variable TO <fs_name>.

Example: Basic Field Symbol Usage

REPORT z_fs_basic.

DATA lv_name TYPE string VALUE 'Daksh'.

FIELD-SYMBOLS: <fs_name> TYPE string.

ASSIGN lv_name TO <fs_name>.

WRITE: 'Before change:', lv_name.
NEW-LINE.

* Change value through the field symbol
<fs_name> = 'LearnSAPFree'.

WRITE: 'After change:', lv_name.

Output:

Before change: Daksh
After change: LearnSAPFree

Notice what happened here. We changed the value through <fs_name>, but lv_name also changed. This is because the Field Symbol is not a separate variable — it is just a pointer to lv_name. When you modify the Field Symbol, you are directly modifying the original variable.


Why Field Symbols are Important — The Performance Advantage

The biggest reason to use Field Symbols is performance. Let me show you the difference between LOOP AT INTO and LOOP AT ASSIGNING.

Traditional Way: LOOP AT INTO (Copies Data)

REPORT z_loop_into.

TYPES: BEGIN OF ty_employee,
         empid  TYPE i,
         name   TYPE string,
         salary TYPE p DECIMALS 2,
       END OF ty_employee.

DATA: lt_employees TYPE TABLE OF ty_employee,
      ls_employee  TYPE ty_employee.

* Add employees
ls_employee-empid = 101. ls_employee-name = 'Daksh'. ls_employee-salary = '55000.00'.
APPEND ls_employee TO lt_employees.
ls_employee-empid = 102. ls_employee-name = 'Priya'. ls_employee-salary = '48000.00'.
APPEND ls_employee TO lt_employees.

* Loop using INTO - each row is COPIED into ls_employee
LOOP AT lt_employees INTO ls_employee.
  ls_employee-salary = ls_employee-salary * '1.10'.  " 10% raise
  MODIFY lt_employees FROM ls_employee.              " Must write back manually!
ENDLOOP.

LOOP AT lt_employees INTO ls_employee.
  WRITE: / ls_employee-empid, ls_employee-name, ls_employee-salary.
ENDLOOP.

See the problem? With INTO, you have to:

  1. Copy the row into the work area
  2. Modify the work area
  3. Use MODIFY to write the changes back to the internal table

That is three operations per row.

Modern Way: LOOP AT ASSIGNING (Direct Access)

REPORT z_loop_assigning.

TYPES: BEGIN OF ty_employee,
         empid  TYPE i,
         name   TYPE string,
         salary TYPE p DECIMALS 2,
       END OF ty_employee.

DATA: lt_employees TYPE TABLE OF ty_employee,
      ls_employee  TYPE ty_employee.

FIELD-SYMBOLS: <fs_emp> TYPE ty_employee.

* Add employees
ls_employee-empid = 101. ls_employee-name = 'Daksh'. ls_employee-salary = '55000.00'.
APPEND ls_employee TO lt_employees.
ls_employee-empid = 102. ls_employee-name = 'Priya'. ls_employee-salary = '48000.00'.
APPEND ls_employee TO lt_employees.

* Loop using ASSIGNING - field symbol points directly to the row
LOOP AT lt_employees ASSIGNING <fs_emp>.
  <fs_emp>-salary = <fs_emp>-salary * '1.10'.  " 10% raise - changes the table directly!
ENDLOOP.

LOOP AT lt_employees INTO ls_employee.
  WRITE: / ls_employee-empid, ls_employee-name, ls_employee-salary.
ENDLOOP.

Output:

101 Daksh 60500.00
102 Priya 52800.00

Look how much cleaner that is. No MODIFY statement needed. No separate work area required for the update. When you change <fs_emp>-salary, you are changing the actual row inside the internal table. One operation instead of three.

Performance Comparison

MethodWhat HappensOperations per RowSpeed
LOOP AT INTOCopies row to work area3 (copy + modify + write back)Slower
LOOP AT ASSIGNINGPoints directly to row1 (direct modification)Faster

For small tables (under 1000 rows), you will not notice the difference. For large tables (10,000+ rows), the performance gap becomes very significant. In production SAP systems that process millions of records daily, this optimization matters a lot.


READ TABLE with ASSIGNING

You can also use Field Symbols with READ TABLE for single-row access:

REPORT z_read_assigning.

TYPES: BEGIN OF ty_product,
         prodid TYPE i,
         name   TYPE string,
         price  TYPE p DECIMALS 2,
       END OF ty_product.

DATA: lt_products TYPE TABLE OF ty_product,
      ls_product  TYPE ty_product.

FIELD-SYMBOLS: <fs_prod> TYPE ty_product.

ls_product-prodid = 1. ls_product-name = 'Keyboard'. ls_product-price = '1500.00'.
APPEND ls_product TO lt_products.
ls_product-prodid = 2. ls_product-name = 'Mouse'. ls_product-price = '800.00'.
APPEND ls_product TO lt_products.
ls_product-prodid = 3. ls_product-name = 'Monitor'. ls_product-price = '12000.00'.
APPEND ls_product TO lt_products.

* Read a specific row using field symbol
READ TABLE lt_products ASSIGNING <fs_prod> WITH KEY prodid = 2.

IF sy-subrc = 0.
  WRITE: 'Found:', <fs_prod>-name, <fs_prod>-price.

  * Update the price directly
  <fs_prod>-price = '950.00'.
  NEW-LINE.
  WRITE: 'Updated price:', <fs_prod>-price.
ELSE.
  WRITE: 'Product not found.'.
ENDIF.

Output:

Found: Mouse 800.00
Updated price: 950.00

After the READ TABLE, <fs_prod> points directly to the Mouse row in the internal table. Changing the price through the Field Symbol updates the actual table.


Checking if a Field Symbol is Assigned

A Field Symbol that has not been assigned to any data is called unassigned. Using an unassigned Field Symbol causes a runtime error (short dump). Always check before using:

REPORT z_fs_check.

FIELD-SYMBOLS: <fs_data> TYPE string.

IF <fs_data> IS ASSIGNED.
  WRITE: 'Field symbol is pointing to data:', <fs_data>.
ELSE.
  WRITE: 'Field symbol is not assigned to anything.'.
ENDIF.

Output:

Field symbol is not assigned to anything.

Unassigning a Field Symbol

You can also detach a Field Symbol from its current data:

UNASSIGN <fs_data>.

After this, the Field Symbol goes back to an unassigned state.


Practical Example: Bulk Update with Conditional Logic

Here is a realistic example that shows why Field Symbols are so useful:

REPORT z_fs_practical.

TYPES: BEGIN OF ty_employee,
         empid  TYPE i,
         name   TYPE string,
         dept   TYPE string,
         salary TYPE p DECIMALS 2,
         bonus  TYPE p DECIMALS 2,
       END OF ty_employee.

DATA: lt_employees TYPE TABLE OF ty_employee,
      ls_employee  TYPE ty_employee.

FIELD-SYMBOLS: <fs_emp> TYPE ty_employee.

* Add employee data
ls_employee-empid = 101. ls_employee-name = 'Daksh'. ls_employee-dept = 'Dev'. ls_employee-salary = '55000.00'.
APPEND ls_employee TO lt_employees.
ls_employee-empid = 102. ls_employee-name = 'Priya'. ls_employee-dept = 'HR'. ls_employee-salary = '48000.00'.
APPEND ls_employee TO lt_employees.
ls_employee-empid = 103. ls_employee-name = 'Rahul'. ls_employee-dept = 'Dev'. ls_employee-salary = '62000.00'.
APPEND ls_employee TO lt_employees.
ls_employee-empid = 104. ls_employee-name = 'Neha'. ls_employee-dept = 'Finance'. ls_employee-salary = '51000.00'.
APPEND ls_employee TO lt_employees.
ls_employee-empid = 105. ls_employee-name = 'Amit'. ls_employee-dept = 'Dev'. ls_employee-salary = '58000.00'.
APPEND ls_employee TO lt_employees.

* Calculate bonus based on department
* Dev: 15% bonus, HR: 10% bonus, Finance: 12% bonus
LOOP AT lt_employees ASSIGNING <fs_emp>.
  CASE <fs_emp>-dept.
    WHEN 'Dev'.
      <fs_emp>-bonus = <fs_emp>-salary * '0.15'.
    WHEN 'HR'.
      <fs_emp>-bonus = <fs_emp>-salary * '0.10'.
    WHEN 'Finance'.
      <fs_emp>-bonus = <fs_emp>-salary * '0.12'.
    WHEN OTHERS.
      <fs_emp>-bonus = <fs_emp>-salary * '0.05'.
  ENDCASE.
ENDLOOP.

* Display results
WRITE: 'ID', 8 'Name', 20 'Dept', 32 'Salary', 46 'Bonus'.
ULINE.

LOOP AT lt_employees ASSIGNING <fs_emp>.
  WRITE: / <fs_emp>-empid, 8 <fs_emp>-name, 20 <fs_emp>-dept,
           32 <fs_emp>-salary, 46 <fs_emp>-bonus.
ENDLOOP.

Output:

ID     Name        Dept        Salary        Bonus
---------------------------------------------------------------
101    Daksh       Dev         55000.00      8250.00
102    Priya       HR          48000.00      4800.00
103    Rahul       Dev         62000.00      9300.00
104    Neha        Finance     51000.00      6120.00
105    Amit        Dev         58000.00      8700.00

Without Field Symbols, this would require a MODIFY statement inside the loop for every single row. With Field Symbols, the bonus values are written directly into the internal table rows. Clean, fast, and no extra code needed.


Field Symbols vs Work Areas — Quick Comparison

FeatureWork Area (INTO)Field Symbol (ASSIGNING)
MemoryCreates a copy of the rowPoints to the original row
ModificationNeeds MODIFY to save changesChanges are automatic
PerformanceSlower for large tablesFaster for large tables
SafetyCannot accidentally change originalCan change original (be careful!)
SyntaxLOOP AT lt INTO lsLOOP AT lt ASSIGNING <fs>

Common Mistakes to Avoid

1. Using an Unassigned Field Symbol

Accessing a Field Symbol before assigning it causes a short dump. Always use IS ASSIGNED to check first, or make sure the ASSIGN or LOOP AT ASSIGNING was successful.

2. Forgetting That Field Symbols Modify the Original

Because Field Symbols point directly to the data, any change you make affects the original immediately. If you only need to read the data without modifying it, consider using INTO with a work area instead.

3. Using Field Symbols After the Loop Ends

After a LOOP AT ASSIGNING ends, the Field Symbol still points to the last row. Modifying it outside the loop changes that last row. This is a common source of hard-to-find bugs.


Interactive Checkpoints

🙋‍♂️ Checkpoint 1: What is the main difference between LOOP AT INTO and LOOP AT ASSIGNING?
LOOP AT INTO copies each row into a separate work area variable. You get an independent copy that you can modify without affecting the original table (unless you explicitly use MODIFY). LOOP AT ASSIGNING makes the Field Symbol point directly to the row in the internal table. Any changes through the Field Symbol immediately modify the actual data in the table. ASSIGNING is faster because it skips the copy operation, but you need to be careful about unintended modifications.
🙋‍♂️ Checkpoint 2: How do you check if a Field Symbol is currently pointing to valid data?
You use the IS ASSIGNED check: IF IS ASSIGNED. This returns true if the Field Symbol is currently pointing to a valid data object, and false if it has not been assigned yet or has been unassigned. Always perform this check before accessing a Field Symbol that might not be assigned, especially after READ TABLE ASSIGNING where the read might fail.
🙋‍♂️ Checkpoint 3: When should you prefer a work area (INTO) over a Field Symbol (ASSIGNING)?
Use a work area when you need a read-only snapshot of the data that you do not want to accidentally modify. For example, if you are building a separate output table by transforming the data, using INTO gives you a safe copy to work with. Also use INTO when the loop body deletes rows from the same table, because Field Symbols can become invalid if the row they point to is deleted during the loop.

Summary

Field Symbols are one of the most important performance optimization tools in ABAP. They eliminate unnecessary copy operations when looping through internal tables, which can make a dramatic difference in programs that process large volumes of data.

The rule of thumb is simple: if you need to modify rows inside a loop, use ASSIGNING. If you just need to read data without changing it, INTO works fine. For large datasets, always prefer ASSIGNING for better performance.

Once you are comfortable with Field Symbols, you will find that almost all professional ABAP code uses them. They are not optional knowledge — they are an essential part of writing efficient, production-quality ABAP programs.

Daksh Dedha - SAP Technical Consultant

Written by Daksh Dedha

SAP Technical Consultant

Daksh is an SAP Technical Consultant specializing in ABAP programming, SAP S/4HANA migrations, Fiori development, and BTP cloud architecture. He authors free, hands-on tutorials to make enterprise SAP education accessible to all developers.

Test Your Knowledge

SAP Challenge Question 1 of 10

Loading question...

Found this tutorial useful? Share it with your SAP development team.