ABAP Keyword Documentation → ABAP - Reference → Processing External Data → ABAP - Database Accesses → Open SQL → Open SQL - Read Accesses → SELECT
SELECT, Dynamic Token Specification
The example illustrates the dynamic Token specification in OpenSQL for the SELECT
statement.
Other versions: 7.31 | 7.40 | 7.54
Source Code
CONSTANTS left TYPE tabname VALUE 'SFLIGHT'.
DATA: right TYPE tabname,
struct_type TYPE REF TO cl_abap_structdescr,
table_type TYPE REF TO cl_abap_tabledescr,
comp_tab1 TYPE cl_abap_structdescr=>component_table,
comp_tab2 TYPE cl_abap_structdescr=>component_table,
comp1 LIKE LINE OF comp_tab1,
comp2 LIKE LINE OF comp_tab2,
select TYPE TABLE OF edpline,
sublist TYPE edpline,
from TYPE string,
first_on TYPE abap_bool VALUE abap_true,
tref TYPE REF TO data,
alv TYPE REF TO cl_salv_table.
FIELD-SYMBOLS <itab> TYPE STANDARD TABLE.
IF spfli = 'X'.
right = 'SPFLI'.
ELSEIF scarr = 'X'.
right = 'SCARR'.
ELSEIF saplane = 'X'.
right = 'SAPLANE'.
ENDIF.
first_on = abap_true.
CLEAR: select, sublist, from.
READ CURRENT LINE LINE VALUE INTO right.
struct_type ?=
cl_abap_typedescr=>describe_by_name( left ).
comp_tab1 = struct_type->get_components( ).
struct_type ?=
cl_abap_typedescr=>describe_by_name( right ).
comp_tab2 = struct_type->get_components( ).
from = left && ` join ` && right && ` on `.
LOOP AT comp_tab1 INTO comp1 WHERE name IS NOT INITIAL.
sublist = left && '~' && comp1-name.
APPEND sublist TO select.
ENDLOOP.
LOOP AT comp_tab2 INTO comp2 WHERE name IS NOT INITIAL.
READ TABLE comp_tab1 INTO comp1
WITH TABLE KEY name = comp2-name.
IF sy-subrc <> 0.
APPEND comp2 TO comp_tab1.
sublist = right && '~' && comp2-name.
APPEND sublist TO select.
ELSE.
IF first_on = abap_false.
from = from && ` and `.
ELSE.
first_on = abap_false.
ENDIF.
from = from && left && `~` && comp2-name &&
` = ` && right && `~` && comp2-name.
ENDIF.
ENDLOOP.
struct_type = cl_abap_structdescr=>create( comp_tab1 ).
table_type = cl_abap_tabledescr=>create( struct_type ).
CREATE DATA tref TYPE HANDLE table_type.
ASSIGN tref->* TO <itab>.
SELECT (select) INTO TABLE <itab> FROM (from).
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = alv
CHANGING t_table = <itab> ).
alv->display( ).
CATCH cx_salv_msg.
MESSAGE 'ALV display not possible' TYPE 'I'
DISPLAY LIKE 'E'.
ENDTRY.
Description
After the program is started, a selection screen with the names of the tables SPFLI, SCARR, and SAPLANE is displayed. The user can select one of the tables, which is then linked to the table SFLIGHT in accordance with its foreign key relationship. This assumes that all fields with the same name have a foreign key relationship with each other. The content of the joined tables is displayed in an ALV Grid Control.
The selected table name is assigned to the field right
. Initially, the RTTS
class CL_ABAP_TYPEDESCR is used to determine the type description for the columns in the left and right
table of the join. The method GET_COMPONENTS_SIMPLE is used to store these in two type description tables
comp_tab1
or comp_tab2
, which contain an entry for each column of the database table in question.
Then, a fragment of the FROM
clause is created, which contains the names
of the tables to be joined; the FROM
clause is later completed using the ON
conditions.
All columns of the left table should be entered in the SELECT
list, as well
as those columns of the right table for which no columns with the same name exist in the left table. The content of the type description tables is processed in loops.
Initially, the columns of the left table are processed. The current column is incorporated first into
the dynamic SELECT
list, which should be specified in the internal table
select
. The column name comp1-name
is prefixed
with the table name in left
, to ensure its uniqueness. The statement
MOVE-CORRESPONDING is used to copy the column description from comp_tab1
to an internal table comp_tab_join
whose type is suitable for creating the objects later.
The columns of the right table are searched in the left table. If the column comp2-name
only exists in the right table, it is, for the time being, incorporated into the type description table
comp_tab_join
. After that, it is added to all columns of the left table of the SELECT
list select
, just like before.
If the column in comp2-name
exists in both tables, an ON
condition that compares columns with the same name from the left and the right table, is added to the dynamic FROM
clause from
.
The type description table comp_tab_join
and the static method CREATE of
the class CL_ABAP_STRUCTDESCR can now be used to create a matching type object for the structure of
the target area of the SELECT
statement. This type object could now be specified
after the addition TYPE HANDLE
of the statement CREATE
DATA to create a structured work area. However, we go one step further and use the method CREATE
of the class CL_ABAP_TABLEDESCR to create a type object for an internal table of this row type and create
this with CREATE DATA
. By assigning the dynamically created internal tables
to a field symbol <itab>
, we create a name for the internal table that
is useable in the INTO
clause of the SELECT
statement.
Direct specification of a dereferencing tref->*
in statements other than
ASSIGN
is only possible if tref
is not generically
typed. However, in our example, tref
is generically typed with TYPE REF TO data
.
Subsequently, the data is read with a completely dynamic SELECT
statement.
The content of the internal table <itab>
is displayed dynamically using class CL_SALV_TABLE.