Common HANA pitfalls
What you'll learn
The classic traps: ORDER BY is no longer free, partial-key SELECT SINGLE is arbitrary, and an empty FOR ALL ENTRIES driver returns every row — so guard it.
- ORDER BY is not free — request it explicitly when you depend on order.
- SELECT SINGLE on a partial key returns an arbitrary row; supply the full key.
- FOR ALL ENTRIES de-duplicates the driver AND returns ALL rows on an empty driver — guard it.
The classics all stem from the §2.1 shifts. ORDER BY is no longer free — if you assumed sorted output you now read 'random' rows; and SELECT SINGLE without a fully-qualified key returns an arbitrary matching row, which on HANA is often a different one than before. The fix for both is to be explicit: request the order you depend on, and never SELECT SINGLE on a partial key when you mean 'a specific row.'
FOR ALL ENTRIES carries two pitfalls that are more damaging under HANA because result-set sizes differ: it silently de-duplicates the driver table, and — critically — an empty driver table returns ALL rows of the target, not none. Always guard with IF lines( itab ) > 0 before the FAE, or you will table-scan production.
The remaining classics are quieter: implicit type conversion in a WHERE clause (comparing a CHAR18 MATNR to a short literal forces padding and can drop the index), COUNT(*) on a wide column-store table is a column scan rather than a free metadata read, and LIKE behaviour depends on HANA collation so CDS pattern filters should use the escape mechanism.
Key points
- ORDER BY is not free — request it explicitly when you depend on order.
- SELECT SINGLE on a partial key returns an arbitrary row; supply the full key.
- FOR ALL ENTRIES de-duplicates the driver AND returns ALL rows on an empty driver — guard it.
- Implicit type conversion in WHERE can cost the index; match the field's type.
- COUNT(*) with a filter on a non-key column is a column scan, not a free count.
Examples
If lt_keys is empty, this returns every row of mara — a full table scan nobody intended.
ABAPselect matnr, mtart from mara
for all entries in @lt_keys
where matnr = @lt_keys-matnr
into table @data(lt_mara).The empty-driver guard turns the dangerous all-rows case into a deliberate no-op.
ABAPif lt_keys is not initial.
select matnr, mtart from mara
for all entries in @lt_keys
where matnr = @lt_keys-matnr
into table @data(lt_mara).
endif.On HANA the 'first' row here is undefined — the read is not ordered.
ABAPselect matnr, ersda from mara
into table @data(lt_mara)
up to 10 rows.An explicit ORDER BY makes the 'first 10' deterministic.
ABAPselect matnr, ersda from mara
order by ersda descending
into table @data(lt_mara)
up to 10 rows.Pitfalls
- Forgetting the IF lines( itab ) > 0 guard before FOR ALL ENTRIES — the empty-driver case silently returns all rows.
- Trusting SELECT ... UP TO n ROWS without ORDER BY to be deterministic.
Source notes: clean-core-curriculum §2.2
Ask Claude
Build a prompt from this lesson + your question and open a fresh Claude chat with it pre-filled — handy for adapting a before/after pattern to your own object.