Initial values and null — ABAP has no null¶
Level: 101 · newcomer
One line: Every ABAP variable holds its type's initial value from the moment it exists — 0, blanks, 00000000, an empty string, an unbound reference — and there is no null: IS INITIAL asks whether a value is that initial value, IS BOUND whether a reference points anywhere, and a real SQL NULL is something you can only meet in Open SQL, with IS NULL.
The initial values¶
| Type | Initial value | Looks like |
|---|---|---|
i, p, f, decfloat |
zero | 0 |
c LENGTH n |
n blanks |
' ' |
n LENGTH n |
n zeros |
'0000' |
d |
'00000000' |
not a date, and not null |
t |
'000000' |
midnight, or nothing — you cannot tell |
string, xstring |
empty | an empty string |
x LENGTH n |
zero bytes | 00 00 |
| reference | unbound | IS NOT BOUND, and also IS INITIAL |
| structure | every component initial | |
| internal table | no rows | lines( ) = 0 |
CLEAR lv resets to this. FREE does the same and releases memory. There is no statement that makes a variable "unset".
The consequences¶
- A date of
00000000is a value. It reaches the database, it sorts before every real date, andSELECT … WHERE enddate > @sy-datumexcludes it — which is why SAP's "no end date" is99991231, not initial. - Zero and absent are the same on arrival. An interface that sends no amount and one that sends
0produce the same ABAP variable. If the difference matters, the payload carries a flag or the interface uses a nullable-aware format. See JSON and XML. IS INITIALon a reference isIS NOT BOUND. Both work;IS BOUNDsays what is meant.- SQL
NULLis different. It arises from an outer join, from a column added after rows existed, or from native SQL. Open SQL reads it into the target's initial value — so once it is in ABAP the distinction is gone, and the only place to test it is in theWHEREwithIS NULL, or withcoalesce( )in the column list.
z_tp_initial_values_and_null.prog.abap — pasted here by tools/check_examples.py. Syntax-checked, never run: abaplint parses and type-checks it against the release in abaplint.json, but no system has produced output for it, so this page shows none.
REPORT z_tp_initial_values_and_null.
" ABAP has no null. Every variable has its type's INITIAL value from the
" moment it exists, and IS INITIAL is the test.
DATA lv_i TYPE i.
DATA lv_c TYPE c LENGTH 3.
DATA lv_d TYPE d.
DATA lv_s TYPE string.
DATA lr_r TYPE REF TO data.
DATA lt_t TYPE string_table.
WRITE: / 'i initial?', xsdbool( lv_i IS INITIAL ), lv_i.
WRITE: / 'c initial?', xsdbool( lv_c IS INITIAL ), '[', lv_c, ']'.
WRITE: / 'd initial?', xsdbool( lv_d IS INITIAL ), lv_d.
WRITE: / 'string initial?', xsdbool( lv_s IS INITIAL ).
WRITE: / 'ref initial?', xsdbool( lr_r IS INITIAL ), 'bound?', xsdbool( lr_r IS BOUND ).
WRITE: / 'table initial?', xsdbool( lt_t IS INITIAL ).
" Initial is a VALUE, so it reaches the database as 0, '' or '00000000'. A
" real SQL NULL can only come from an outer join or a column added after the
" rows were, and Open SQL tests it with IS NULL -- a different question.
SELECT c~carrid, f~connid
FROM scarr AS c
LEFT OUTER JOIN sflight AS f ON f~carrid = c~carrid
WHERE f~connid IS NULL
INTO TABLE @DATA(lt_no_flights).
WRITE: / 'carriers with no flight rows', lines( lt_no_flights ).
" CLEAR returns a variable to its initial value. It does not make it null,
" because there is no null to make it.
lv_i = 5.
CLEAR lv_i.
WRITE: / 'after CLEAR', lv_i.
" The consequence for interfaces: "no value sent" and "zero sent" arrive
" identically. If the difference matters, the payload needs a flag.
If you are coming from another language¶
- Go. Zero values, exactly — Go and ABAP agree here, and both use "is it the zero value" as the idiom.
- Java / C# / Python / JavaScript.
null/None/undefinedexist, and their absence in ABAP is the adjustment: there is noNullPointerExceptionon a value, only on a reference (IS BOUND), and no way to say "unknown" without an extra field. - SQL. Three-valued logic stops at the Open SQL boundary; inside ABAP everything is two-valued.
See also¶
- Types at a glance — every type's initial value in one program
- Data references —
IS BOUND IFandCASE—IS INITIAL,IS BOUND,IS ASSIGNED- Open SQL — outer joins and
IS NULL - Dates and times — the
00000000and99991231conventions