Field Symbols in ABAP – Dynamic Data Access Explained for Beginners
Table of Contents
- • What is a Field Symbol?
- ↳ Key Properties:
- • Basic Syntax
- ↳ Declaring a Field Symbol
- ↳ Assigning a Variable to a Field Symbol
- ↳ Example: Basic Field Symbol Usage
- ↳ Output:
- • Why Field Symbols are Important — The Performance Advantage
- ↳ Traditional Way: LOOP AT INTO (Copies Data)
- ↳ Modern Way: LOOP AT ASSIGNING (Direct Access)
- ↳ Output:
- ↳ Performance Comparison
- • READ TABLE with ASSIGNING
- ↳ Output:
- • Checking if a Field Symbol is Assigned
- ↳ Output:
- ↳ Unassigning a Field Symbol
- • Practical Example: Bulk Update with Conditional Logic
- ↳ Output:
- • Field Symbols vs Work Areas — Quick Comparison
- • Common Mistakes to Avoid
- ↳ 1. Using an Unassigned Field Symbol
- ↳ 2. Forgetting That Field Symbols Modify the Original
- ↳ 3. Using Field Symbols After the Loop Ends
- • Interactive Checkpoints
- • Summary
![]()
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:
- Copy the row into the work area
- Modify the work area
- 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
| Method | What Happens | Operations per Row | Speed |
|---|---|---|---|
| LOOP AT INTO | Copies row to work area | 3 (copy + modify + write back) | Slower |
| LOOP AT ASSIGNING | Points directly to row | 1 (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
| Feature | Work Area (INTO) | Field Symbol (ASSIGNING) |
|---|---|---|
| Memory | Creates a copy of the row | Points to the original row |
| Modification | Needs MODIFY to save changes | Changes are automatic |
| Performance | Slower for large tables | Faster for large tables |
| Safety | Cannot accidentally change original | Can change original (be careful!) |
| Syntax | LOOP AT lt INTO ls | LOOP 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?
🙋♂️ Checkpoint 2: How do you check if a Field Symbol is currently pointing to valid data?
🙋♂️ Checkpoint 3: When should you prefer a work area (INTO) over a Field Symbol (ASSIGNING)?
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.
Written by Daksh Dedha
SAP Technical ConsultantDaksh 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
Loading question...
Quiz Completed
Related Tutorials
SAP ABAP Enhancement Framework — User Exits, BADIs, and Enhancement Points
Master SAP ABAP enhancements. Learn User Exits, Customer Exits, BADIs, Enhancement Points, and Implicit/Explicit Enhancement Spots to modify standard SAP without modifying source code.
ABAP ProgrammingABAP CDS Views — Core Data Services Complete Guide for Beginners
Learn ABAP CDS Views from scratch. Understand how to create CDS views in Eclipse ADT, use annotations, associations, parameters, and build OData services with CDS.
ABAP ProgrammingMessage Handling in SAP ABAP — Complete SE91 Message Classes Guide
Master SAP ABAP message handling. Learn how to create message classes in transaction SE91, use the MESSAGE statement, handle error types A E W I S X, and pass placeholders.
Found this tutorial useful? Share it with your SAP development team.