Update example

This commit is contained in:
danrega
2023-03-08 12:33:09 +01:00
parent f97bd6cef1
commit 18384bb0ea
2 changed files with 129 additions and 7 deletions

View File

@@ -942,7 +942,44 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
**********************************************************************
output->next_section( `25) Dynamic Invoke` ).
output->next_section( `25) Excursion: Multiple Dynamically Specified ` &&
`Clauses in an ABAP SQL SELECT Statement` ).
"In this nonsense example, multiple clauses in a SELECT statement are
"determined at runtime to demonstrate the rich variety of possibilities.
"Note: The rows and target table specifications are not real dynamic specifications in the
"SELECT statement in the sense of syntax elements enclosed by parentheses. Here, they are just
"included to provide some more 'dynamic' touch of the statement :)
"Getting all clauses of the SELECT statement
DATA(dyn_syntax_elem) = lcl_det_at_runtime=>get_dyn_syntax_elements( ).
IF dyn_syntax_elem-table IS NOT INITIAL
AND dyn_syntax_elem-select_list IS NOT INITIAL
AND dyn_syntax_elem-where_clause IS NOT INITIAL
AND dyn_syntax_elem-order_by IS NOT INITIAL
AND dyn_syntax_elem-target IS BOUND
AND dyn_syntax_elem-rows IS NOT INITIAL.
output->display( `Dynamically determined syntax elements:` ).
output->display( input = dyn_syntax_elem name = `dyn_syntax_elem` ).
SELECT (dyn_syntax_elem-select_list)
FROM (dyn_syntax_elem-table)
WHERE (dyn_syntax_elem-where_clause)
ORDER BY (dyn_syntax_elem-order_by)
INTO CORRESPONDING FIELDS OF TABLE @dyn_syntax_elem-target->*
UP TO @dyn_syntax_elem-rows ROWS.
output->display( input = dyn_syntax_elem-target->* name = `dyn_syntax_elem-target->*` ).
ELSE.
output->display( `There's an issue with syntax elements.` ).
ENDIF.
**********************************************************************
output->next_section( `26) Dynamic Invoke` ).
"In the example, both class and method are determined at runtime for
"the method call. The suitable parameter table is filled in the
@@ -983,7 +1020,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
**********************************************************************
output->next_section( `26) RTTI: Determining Data and Object Types at Runtime` ).
output->next_section( `27) RTTI: Determining Data and Object Types at Runtime` ).
"The example demonstrates RTTI as follows:
"- The method call takes care of providing the name of a type. It is implemented
@@ -1122,7 +1159,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
**********************************************************************
output->next_section( `27) RTTC: Dynamically Creating Elementary Data Objects` ).
output->next_section( `28) RTTC: Dynamically Creating Elementary Data Objects` ).
"The example demonstrates RTTC as follows:
"- The method call takes care of providing the name of a built-in data type and more
@@ -1161,7 +1198,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
**********************************************************************
output->next_section( `28) RTTC: Dynamically Creating Structured Data Object (1)` ).
output->next_section( `29) RTTC: Dynamically Creating Structured Data Object (1)` ).
"The example demonstrates RTTC as follows:
"- The method call takes care of providing the name of a database table name.
@@ -1199,7 +1236,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
**********************************************************************
output->next_section( `29) RTTC: Dynamically Creating Structured Data Object (2)` ).
output->next_section( `30) RTTC: Dynamically Creating Structured Data Object (2)` ).
"This example includes the dynamic definition of a structure with three components
"using the GET method of the CL_ABAP_STRUCTDESCR class.
@@ -1255,7 +1292,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
**********************************************************************
output->next_section( `30) RTTC: Dynamically Creating Internal Table (1)` ).
output->next_section( `31) RTTC: Dynamically Creating Internal Table (1)` ).
"The example demonstrates RTTC as follows:
"- The method call takes care of providing the name of a database table name.
@@ -1282,7 +1319,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
**********************************************************************
output->next_section( `31) RTTC: Dynamically Creating Internal Table (2)` ).
output->next_section( `32) RTTC: Dynamically Creating Internal Table (2)` ).
"In the example an internal table type is created based on a DDIC type.
"See the comments in the code.

View File

@@ -20,6 +20,15 @@ CLASS lcl_det_at_runtime DEFINITION.
dec TYPE i,
END OF struc_builtin.
TYPES: BEGIN OF struc_dyn,
table TYPE string,
select_list TYPE string,
where_clause TYPE string_table,
order_by TYPE string,
target TYPE REF TO data,
rows TYPE i,
END OF struc_dyn.
CLASS-METHODS:
get_dyn_table_name RETURNING VALUE(tab) TYPE string,
get_dyn_dobj RETURNING VALUE(dobj) TYPE string,
@@ -31,6 +40,7 @@ CLASS lcl_det_at_runtime DEFINITION.
get_dyn_class_meth EXPORTING cl TYPE string
meth TYPE string
ptab TYPE abap_parmbind_tab,
get_dyn_syntax_elements RETURNING VALUE(syntax_elements) TYPE struc_dyn,
fill_string.
PROTECTED SECTION.
@@ -289,6 +299,81 @@ CLASS lcl_det_at_runtime IMPLEMENTATION.
dyn_meth_call_result = |Hallo { sy-uname }. The string was filled at { utclong_current( ) }.|.
ENDMETHOD.
METHOD get_dyn_syntax_elements.
"FROM clause
DATA(flight_tables) = VALUE string_table(
( `ZDEMO_ABAP_CARR` ) ( `ZDEMO_ABAP_FLSCH` ) ( `ZDEMO_ABAP_FLI` ) ).
"Getting random number to determine the table index at runtime.
DATA(idx_table) = cl_abap_random_int=>create(
seed = cl_abap_random=>seed( )
min = 1
max = lines( flight_tables ) )->get_next( ).
syntax_elements-table = VALUE #( flight_tables[ idx_table ] DEFAULT `ZDEMO_ABAP_CARR` ).
"SELECT list
DATA(comp) = CAST cl_abap_structdescr(
cl_abap_typedescr=>describe_by_name( syntax_elements-table ) )->components.
"At least 3 components
DATA(idx_comp) = cl_abap_random_int=>create(
seed = cl_abap_random=>seed( )
min = 3
max = lines( comp ) )->get_next( ).
DELETE comp FROM idx_comp + 1 TO lines( comp ).
LOOP AT comp ASSIGNING FIELD-SYMBOL(<comp>).
syntax_elements-select_list = syntax_elements-select_list && `, ` && <comp>-name.
ENDLOOP.
"Replacing initial comma
REPLACE PCRE `^,\s` IN syntax_elements-select_list WITH ``.
"WHERE clause
"Excluding the client field
DELETE comp WHERE name = 'MANDT'.
"A maximum of 4 fields are to be respected because that is the maximum of possible fields
"available in table zdemo_abap_carr (without the client field)
DATA(idx_where) = cl_abap_random_int=>create(
seed = cl_abap_random=>seed( )
min = 1
max = 4 )->get_next( ).
"In the example, the WHERE clause consists of an internal table of type string.
"The clause is set up with fields and only IS NOT INITIAL to be on the safe side for a
"somewhat 'meaningful' clause and in the interest of simplicity.
LOOP AT comp ASSIGNING FIELD-SYMBOL(<where>) TO idx_where.
IF sy-tabix = 1.
APPEND <where>-name && ` IS NOT INITIAL` TO syntax_elements-where_clause.
ELSE.
APPEND `OR ` && <where>-name && ` IS NOT INITIAL` TO syntax_elements-where_clause.
ENDIF.
ENDLOOP.
"ORDER BY clause
DATA(idx_order) = cl_abap_random_int=>create(
seed = cl_abap_random=>seed( )
min = 1
max = lines( comp ) )->get_next( ).
syntax_elements-order_by = VALUE #( comp[ idx_order ]-name DEFAULT `CARRID` ).
"INTO clause
CREATE DATA syntax_elements-target TYPE TABLE OF (syntax_elements-table).
"UP TO ... ROWS
"A minimum of 2 and a maximum of 6 rows are to be retrieved by the SELECT statement
syntax_elements-rows = cl_abap_random_int=>create(
seed = cl_abap_random=>seed( )
min = 2
max = 6 )->get_next( ).
ENDMETHOD.
ENDCLASS.
CLASS lcl_demo1 DEFINITION.