Very simple query builder (“query optimizer”) for ABAP Open SQL.
Sometimes you need to build a SELECT dynamically based on:
- which fields the caller wants to select,
- which filters are provided,
- and which JOINed tables are actually needed.
If you have a large JOIN across many tables, but some of those tables are only needed in special scenarios, joining them all the time will slow down the query.
This query builder helps by generating the following parts as strings:
- the result field list (
SELECT (lv_result)), - the
FROMclause including only the necessary JOINs, - the
WHEREclause.
Important: it only adds “touched” tables (tables that appear in the result list or in the WHERE conditions).
Note: This is a simple utility. It is not perfect, but it is practical.
Goal: select orders from CRMD_ORDERADM_H.
By default, the builder uses Open SQL syntax, so ABAP variables must be prefixed with @.
DATA(lro_qb) = NEW lcl_query_builder(
table = 'CRMD_ORDERADM_H'
alias = 'H' ).lro_qb->add_join(
table = 'CRMD_ORDER_INDEX'
alias = 'IC'
pred = 'H'
on = 'IC~HEADER EQ H~GUID' ).lro_qb->add_where( field = 'H~PROCESS_TYPE' op = 'EQ' value = |'PRTY'| ).
lro_qb->add_result( 'H~GUID' ).
lro_qb->add_result( 'H~OBJECT_ID' ).
lro_qb->add_result( 'H~PROCESS_TYPE' ).In some scenarios the user filters by partner function and also wants to see it in the result.
Assume the partner range is stored in a global range table GT_COMPT.
To add a range table, pass its name as a string with @ prefix (because it will be concatenated into a dynamic WHERE string).
If you need string constants in dynamic conditions, make sure to include the quotes (as in |'X'|).
IF gt_compt[] IS NOT INITIAL.
lro_qb->add_where( field = 'IC~PARTNER_NO' value = '@GT_COMPT' ).
lro_qb->add_where( field = 'IC~PFT_9' op = 'EQ' value = |'X'| ).
lro_qb->add_result( field = 'IC~PARTNER_NO' alias = 'COMPETITOR_NO' ).
ENDIF.DATA(lv_result) = lro_qb->get_result( ).
DATA(lv_from) = lro_qb->get_from( ).
DATA(lv_where) = lro_qb->get_where( ).SELECT (lv_result)
INTO CORRESPONDING FIELDS OF @lt_data
FROM (lv_from)
WHERE (lv_where).If gt_compt[] contains data, the following SELECT will be executed:
SELECT H~GUID, H~OBJECT_ID, H~PROCESS_TYPE, IC~PARTNER_NO AS COMPETITOR_NO
FROM CRMD_ORDERADM_H AS H
JOIN CRMD_ORDER_INDEX AS IC
ON IC~HEADER EQ H~GUID
WHERE H~PROCESS_TYPE EQ 'PRTY'
AND IC~PARTNER_NO IN @GT_COMPT
AND IC~PFT_9 EQ 'X'.Otherwise:
SELECT H~GUID, H~OBJECT_ID, H~PROCESS_TYPE
FROM CRMD_ORDERADM_H AS H
WHERE H~PROCESS_TYPE EQ 'PRTY'.