Update
This commit is contained in:
@@ -1781,23 +1781,18 @@ The type properties are represented by attributes that are accessible through th
|
||||
> - For each type category (elementary type, table, and so on), there is a type description class (e.g. `CL_ABAP_STRUCTDESCR` for structures, as shown in the hierarchy tree above) that has special attributes (i.e. the properties of the respective types).
|
||||
> - References to type description objects can be used, for example, after the `TYPE HANDLE` addition of the `CREATE DATA` and `ASSIGN` statements.
|
||||
|
||||
The following examples show the retrieval of type information. Instead of the extra declaration of data reference variables, you can use
|
||||
[inline declarations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry").
|
||||
[Method chaining](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmethod_chaining_glosry.htm "Glossary Entry")
|
||||
comes in handy, too.
|
||||
|
||||
|
||||
The following example explores the RTTI type hierarchy and demonstrates how to retrieve various pieces of type information using RTTI attributes and methods. You can create a demo class (adapt the class name if needed), copy and paste the code, run the class with F9 in ADT, and check the output in the console.
|
||||
|
||||
The example includes demo objects that are added to an internal table. This table is then looped over to retrieve type information for all objects. To retrieve a type description object, you have multiple options. One option is to use the static methods of the `cl_abap_typedescr` class, which is the root class of the RTTI hierarchy. These methods include:
|
||||
The example includes demo objects that are added to an internal table. This table is then looped over to retrieve type information for all objects. To retrieve a type description object, you have multiple options. You can use the static methods of the `cl_abap_typedescr` class, which is the root class of the RTTI hierarchy. These methods include:
|
||||
- `describe_by_data`: Returns an object reference in one of the classes `cl_abap_elemdescr`, `cl_abap_enumdescr`, `cl_abap_refdescr`, `cl_abap_structdescr`, or `cl_abap_tabledsecr`.
|
||||
- `describe_by_object_ref`: Returns the type that an object reference variable points to.
|
||||
- `describe_by_data_ref`: Returns the type that a data reference variable points to.
|
||||
- `describe_by_name`: Returns a type description object when providing the relative or absolute name of a type.
|
||||
|
||||
Notes:
|
||||
- The `*_ref` methods return objects of the dynamic type.
|
||||
- In the bigger example of the demo class, we do not use type names, but rather objects (`describe_by_name` is used in the smaller example in the demo class). Therefore, we first try to get a type description object using the `describe_by_object_ref` method to obtain an instance of `cl_abap_objectdescr`. If this fails, it means we have an instance of `cl_abap_datadescr`, which is the next subclass in the hierarchy. We can retrieve this using the `describe_by_data` method.
|
||||
- The `describe_by_data` method also works for references, including object/interface reference variables. In these cases, the returned object points to `cl_abap_refdescr`. We can then use the `get_referenced_type` method to obtain more details about the actual reference.
|
||||
- In the bigger example of the demo class (the first `LOOP` statement), type names are not used, but rather objects. First, an attempt is made to get a type description object using the `describe_by_object_ref` method to obtain an instance of `cl_abap_objectdescr`. If this fails, it means it is an instance of `cl_abap_datadescr`, which is the next subclass in the hierarchy. It can be retrieved using the `describe_by_data` method. `describe_by_name` is used in the smaller example in the demo class (the second `LOOP` statement).
|
||||
- The `describe_by_data` method also works for references, including object/interface reference variables. In these cases, the returned object points to `cl_abap_refdescr`. The `get_referenced_type` method can then be used to obtain more details about the actual reference.
|
||||
- The example also demonstrates the dynamic creation of data objects using the retrieved type description objects and the `HANDLE` addition to the `CREATE DATA` statement. It also shows dynamic creations using the dynamic specification of the type and the absolute name. The latter is also possible with the `CREATE OBJECT` statement to create objects dynamically. In ABAP for Cloud Development, absolute names having the pattern `\TYPE=%_...` (an internal technical name that is available for [bound data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbound_data_type_glosry.htm)) cannot be used for the dynamic creation.
|
||||
- To visualize the retrieved information, many values are added to a string table. Note that this example is tailored to cover all subclasses of the RTTI hierarchy, but it does not explore all available options for information retrieval.
|
||||
- The example uses artifacts from the ABAP cheat sheet repository.
|
||||
@@ -1830,7 +1825,7 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
"Elementary type
|
||||
DATA elem_dobj TYPE c LENGTH 4 VALUE 'ABAP'.
|
||||
|
||||
"Enumeration type
|
||||
"Enumerated type
|
||||
TYPES: BEGIN OF ENUM enum_t,
|
||||
enum1,
|
||||
enum2,
|
||||
@@ -1947,18 +1942,18 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
IF tdo IS INSTANCE OF cl_abap_elemdescr.
|
||||
INSERT |{ tabix } Is instance of cl_abap_elemdescr| INTO TABLE str_tab.
|
||||
|
||||
"Enumeration types
|
||||
"Enumerated types
|
||||
IF tdo IS INSTANCE OF cl_abap_enumdescr.
|
||||
INSERT |{ tabix } Is instance of cl_abap_enumdescr| INTO TABLE str_tab.
|
||||
|
||||
DATA(enum) = CAST cl_abap_enumdescr( tdo ).
|
||||
|
||||
"Various type-specific information retrieval
|
||||
"Base type of enumeration type
|
||||
"Base type of enumerated type
|
||||
DATA(enum_base_type_kind) = enum->base_type_kind.
|
||||
INSERT |{ tabix } Base type: { enum_base_type_kind }| INTO TABLE str_tab.
|
||||
|
||||
"Elements of the enumeration type
|
||||
"Elements of the enumerated type
|
||||
DATA(enum_elements) = enum->members.
|
||||
INSERT |{ tabix } Elements:| &&
|
||||
| { REDUCE string( INIT str = `` FOR <l> IN enum_elements NEXT str = |{ str }{ COND #( WHEN str IS NOT INITIAL THEN ` / ` ) }| &&
|
||||
@@ -1988,7 +1983,7 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
INSERT |{ tabix } Dynamic data object creation error: { err_enum->get_text( ) }| INTO TABLE str_tab.
|
||||
ENDTRY.
|
||||
|
||||
"Elementary types other than enumeration types
|
||||
"Elementary types other than enumerated types
|
||||
ELSE.
|
||||
DATA(elem) = CAST cl_abap_elemdescr( tdo ).
|
||||
|
||||
@@ -2111,8 +2106,7 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
DATA(struc_components) = struc->components.
|
||||
INSERT |{ tabix } Components 1: | &&
|
||||
|{ REDUCE string( INIT str = `` FOR <comp1> IN struc_components NEXT str = |{ str }| &&
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN ` / ` ) }{ <comp1>-name } ({ <comp1>-type_kind })| ) }|
|
||||
INTO TABLE str_tab.
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN ` / ` ) }{ <comp1>-name } ({ <comp1>-type_kind })| ) }| INTO TABLE str_tab.
|
||||
|
||||
"Structure components (more details)
|
||||
"The following method also returns a table with component information. In this case,
|
||||
@@ -2121,8 +2115,7 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
DATA(struc_components_tab) = struc->get_components( ).
|
||||
INSERT |{ tabix } Components 2: | &&
|
||||
|{ REDUCE string( INIT str = `` FOR <comp2> IN struc_components_tab NEXT str = |{ str }| &&
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN ` / ` ) }{ <comp2>-name } ({ <comp2>-type->type_kind })| ) }|
|
||||
INTO TABLE str_tab.
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN ` / ` ) }{ <comp2>-name } ({ <comp2>-type->type_kind })| ) }| INTO TABLE str_tab.
|
||||
|
||||
"Checking if the structure has includes
|
||||
DATA(struc_has_include) = struc->has_include.
|
||||
@@ -2133,16 +2126,14 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
DATA(struc_incl_view) = struc->get_included_view( ).
|
||||
INSERT |{ tabix } Included view: | &&
|
||||
|{ REDUCE string( INIT str = `` FOR <comp3> IN struc_incl_view NEXT str = |{ str }| &&
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN `, ` ) }{ <comp3>-name }| ) }|
|
||||
INTO TABLE str_tab.
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN `, ` ) }{ <comp3>-name }| ) }| INTO TABLE str_tab.
|
||||
|
||||
"Returning component names of all components and substructures in included
|
||||
"structures that contain included structures
|
||||
DATA(struc_all_incl) = struc->get_symbols( ).
|
||||
INSERT |{ tabix } Included view: | &&
|
||||
|{ REDUCE string( INIT str = `` FOR <comp4> IN struc_all_incl NEXT str = |{ str }| &&
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN `, ` ) }{ <comp4>-name }| ) }|
|
||||
INTO TABLE str_tab.
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN `, ` ) }{ <comp4>-name }| ) }| INTO TABLE str_tab.
|
||||
ENDIF.
|
||||
|
||||
"Checking the type compatibility of the data object
|
||||
@@ -2203,8 +2194,7 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
INSERT |{ tabix } Table keys: { REDUCE string( INIT str = `` FOR <key2> IN tab_keys NEXT str = |{ str }| &&
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN `, ` ) }{ REDUCE string( INIT str2 = `` FOR <key3> IN <key2>-components NEXT str2 = |{ str2 }| &&
|
||||
|{ COND #( WHEN str2 IS NOT INITIAL THEN `/` ) }{ <key3>-name }| ) } (is primary: "{ <key2>-is_primary }", | &&
|
||||
|is unique: "{ <key2>-is_unique }", key kind: "{ <key2>-key_kind }", access kind: "{ <key2>-access_kind }")| ) }|
|
||||
INTO TABLE str_tab.
|
||||
|is unique: "{ <key2>-is_unique }", key kind: "{ <key2>-key_kind }", access kind: "{ <key2>-access_kind }")| ) }| INTO TABLE str_tab.
|
||||
|
||||
DATA(tab_keys_aliases) = tab->get_key_aliases( ).
|
||||
IF tab_keys_aliases IS NOT INITIAL.
|
||||
@@ -2292,8 +2282,7 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
DATA(obj_ref_attributes) = obj_ref->attributes.
|
||||
|
||||
INSERT |{ tabix } Attributes: { REDUCE string( INIT str = `` FOR <attr> IN obj_ref_attributes NEXT str = |{ str }| &&
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN `, ` ) }{ <attr>-name } (vis: "{ <attr>-visibility }", static: "{ <attr>-is_class }")| ) }|
|
||||
INTO TABLE str_tab.
|
||||
|{ COND #( WHEN str IS NOT INITIAL THEN `, ` ) }{ <attr>-name } (vis: "{ <attr>-visibility }", static: "{ <attr>-is_class }")| ) }| INTO TABLE str_tab.
|
||||
|
||||
"Getting the interfaces implemented
|
||||
DATA(obj_ref_interfaces) = obj_ref->interfaces.
|
||||
@@ -2341,8 +2330,7 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
IF absolute_name CS '\CLASS=ZCL_DEMO_ABAP_OBJECTS' AND err_obj IS INITIAL.
|
||||
INSERT |{ tabix } Dynamic attribute access: { REDUCE string( INIT str = `` FOR <m> IN obj_ref_attributes NEXT str = |{ str }| &&
|
||||
|{ COND #( WHEN str IS NOT INITIAL AND <m>-visibility = 'U' THEN ` / ` ) }| &&
|
||||
|{ COND #( WHEN <m>-visibility = 'U' THEN <m>-name && ` ("` && CONV string( dyn_obj->(<m>-name) ) && `")` ) }| ) }|
|
||||
INTO TABLE str_tab.
|
||||
|{ COND #( WHEN <m>-visibility = 'U' THEN <m>-name && ` ("` && CONV string( dyn_obj->(<m>-name) ) && `")` ) }| ) }| INTO TABLE str_tab.
|
||||
ENDIF.
|
||||
|
||||
"-----------------------------------------------------------------------
|
||||
@@ -2456,7 +2444,7 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
"Elementary type
|
||||
TYPES packed TYPE p LENGTH 8 DECIMALS 2.
|
||||
|
||||
"Enumeration type
|
||||
"Enumerated type
|
||||
TYPES: BEGIN OF ENUM enum_type,
|
||||
enum_a,
|
||||
enum_b,
|
||||
@@ -2474,7 +2462,9 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
|
||||
"Internal table types
|
||||
TYPES int_tab_type TYPE TABLE OF i WITH EMPTY KEY.
|
||||
TYPES sorted_tab_type TYPE SORTED TABLE OF flat_struc_type WITH UNIQUE KEY a WITH NON-UNIQUE SORTED KEY sec_key ALIAS sk COMPONENTS b c.
|
||||
TYPES sorted_tab_type TYPE SORTED TABLE OF flat_struc_type
|
||||
WITH UNIQUE KEY a
|
||||
WITH NON-UNIQUE SORTED KEY sec_key ALIAS sk COMPONENTS b c.
|
||||
TYPES itab_der_type TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m.
|
||||
|
||||
"Reference types
|
||||
@@ -2482,20 +2472,20 @@ CLASS zcl_some_class IMPLEMENTATION.
|
||||
TYPES gen_dref_type TYPE REF TO data.
|
||||
"Class and interface names are specified directly
|
||||
|
||||
DATA(type_names) = VALUE string_table( ( `PACKED` ) "Elementary type (1)
|
||||
( `TIMESTAMPL` ) "Elementary type, global DDIC type/data element (2)
|
||||
( `ENUM_TYPE` ) "Enumeration type (3)
|
||||
( `FLAT_STRUC_TYPE` ) "Structured type, flat structure (4)
|
||||
( `STR_DER_TYPE` ) "Structured type, BDEF derived type (5)
|
||||
( `INT_TAB_TYPE` ) "Table type, elementary line type (6)
|
||||
( `SORTED_TAB_TYPE` ) "Table type, structured line type (7)
|
||||
( `ITAB_DER_TYPE` ) "Table type, BDEF derived type (8)
|
||||
( `INT_DREF_TYPE` ) "Reference type (9)
|
||||
( `GEN_DREF_TYPE` ) "Reference type, generic type (10)
|
||||
( `CL_ABAP_TYPEDESCR` ) "Class name (11)
|
||||
( `CL_ABAP_CORRESPONDING` ) "Class name (12)
|
||||
( `IF_OO_ADT_CLASSRUN` ) "Interface name (13)
|
||||
( `ZDEMO_ABAP_OBJECTS_INTERFACE` ) "Interface name (14)
|
||||
DATA(type_names) = VALUE string_table( ( `PACKED` ) "Elementary type (1)
|
||||
( `TIMESTAMPL` ) "Elementary type, global DDIC type/data element (2)
|
||||
( `ENUM_TYPE` ) "Enumerated type (3)
|
||||
( `FLAT_STRUC_TYPE` ) "Structured type, flat structure (4)
|
||||
( `STR_DER_TYPE` ) "Structured type, BDEF derived type (5)
|
||||
( `INT_TAB_TYPE` ) "Table type, elementary line type (6)
|
||||
( `SORTED_TAB_TYPE` ) "Table type, structured line type (7)
|
||||
( `ITAB_DER_TYPE` ) "Table type, BDEF derived type (8)
|
||||
( `INT_DREF_TYPE` ) "Reference type (9)
|
||||
( `GEN_DREF_TYPE` ) "Reference type, generic type (10)
|
||||
( `CL_ABAP_TYPEDESCR` ) "Class name (11)
|
||||
( `CL_ABAP_CORRESPONDING` ) "Class name (12)
|
||||
( `IF_OO_ADT_CLASSRUN` ) "Interface name (13)
|
||||
( `ZDEMO_ABAP_OBJECTS_INTERFACE` ) "Interface name (14)
|
||||
).
|
||||
|
||||
LOOP AT type_names INTO DATA(type_name).
|
||||
@@ -2542,7 +2532,8 @@ ENDCLASS.
|
||||
|
||||
#### Excursion: Inline Declaration, CAST Operator, Method Chaining
|
||||
|
||||
As shown in the example above, you can use inline declaration, the `CAST` operator for casting, and method chaining to write more concise code and avoid declaring helper variables. However, also consider the code's debuggability, maintainability, and readability.
|
||||
As shown in the example above, you can use [inline declarations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry"), the [`CAST`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_cast.htm) operator for casting, and [method chaining](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmethod_chaining_glosry.htm "Glossary Entry") to write more concise code and avoid declaring helper variables. However, also consider the code's debuggability, maintainability, and readability.
|
||||
|
||||
|
||||
```abap
|
||||
DATA some_struc TYPE zdemo_abap_carr.
|
||||
|
||||
74
12_AMDP.md
74
12_AMDP.md
@@ -382,58 +382,29 @@ You can then use the CDS table function as source for a
|
||||
|
||||
## More Information
|
||||
|
||||
Notes on using AMDP in environments with restricted language version (in
|
||||
contrast unrestricted language version):
|
||||
**... on AMDP in ABAP for Cloud Development**
|
||||
|
||||
AMDP methods ...
|
||||
Find more information in the subtopics of the [ABAP Keyword Documentation (ABAP for Cloud Development)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenamdp.htm).
|
||||
|
||||
- must include the addition <code>OPTIONS READ-ONLY</code> in the
|
||||
declaration part.
|
||||
- must be implemented in SQLScript in any case.
|
||||
- cannot use the additions [`USING SCHEMA` (F1 documentation for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapmethod_by_db_proc.htm#!ABAP_ADDITION_5@5@)
|
||||
and [`SUPPRESS SYNTAX ERRORS` (F1 documentation for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapmethod_by_db_proc.htm#!ABAP_ADDITION_3@3@)
|
||||
in the method implementation part
|
||||
- cannot use [AMDP
|
||||
macros](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenamdp_macros.htm)
|
||||
and call hints.
|
||||
- can only use your own entities and entities that are released for
|
||||
the restricted language version after <code>USING</code>.
|
||||
- cannot use
|
||||
[`CONNECTION` (F1 documentation for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenamdp_db_connections.htm)
|
||||
parameters.
|
||||
- cannot raise the
|
||||
`CX_AMDP_CONNECTION_ERROR` exception since
|
||||
the `CONNECTION` parameter is not allowed.
|
||||
> **💡 Note**<br>
|
||||
> - In ABAP for Cloud Development, AMDP methods must be client-safe. This means that the SQLScript code should only access artifacts that restrict access to a single client, such as CDS view entities, or are client-independent. Therefore, all objects used in the `USING` list must be client-safe. This also applies to CDS table functions implemented as AMDP methods. Accessing client-dependent data using methods like Native SQL is not supported in ABAP for Cloud Development.
|
||||
> - The AMDP example for ABAP for Cloud Development is designed differently compared to the AMDP example for Standard ABAP. Instead of using demo database tables, CDS view entities are used in the `USING` list. Additionally, the client handling is adjusted for the AMDP methods by including appropriate additions in the AMDP method declaration part.
|
||||
|
||||
As mentioned above and hinted in the bullet points above, AMDP has more
|
||||
options regarding the unrestricted language version. Check the subtopics
|
||||
[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenamdp.htm).
|
||||
A fundamental question in [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm) with an unrestricted
|
||||
language scope can be whether AMDP is supported at all. The constant
|
||||
`CALL_AMDP_METHOD` of the class
|
||||
`CL_ABAP_DBFEATURES` can be used to query
|
||||
whether the current database supports AMDP methods. See the following
|
||||
snippet:
|
||||
**... on AMDP in Standard ABAP**
|
||||
|
||||
```abap
|
||||
IF NOT cl_abap_dbfeatures=>use_features(
|
||||
EXPORTING requested_features =
|
||||
VALUE #( ( cl_abap_dbfeatures=>call_amdp_method ) ) ).
|
||||
Find more information in the subtopics of the [ABAP Keyword Documentation (Standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenamdp.htm).
|
||||
|
||||
"Result: Current database system does not support AMDP procedures
|
||||
RETURN.
|
||||
ENDIF.
|
||||
```
|
||||
|
||||
This check is not required (and possible) for [ABAP Cloud](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_cloud_glosry.htm) since it is SAP HANA-only anyway and database connections are not
|
||||
possible. Furthermore, another topic that should be noted is that AMDP
|
||||
does not support [implicit client
|
||||
handling](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_sql_client_handling.htm).
|
||||
Therefore, the parameter interface of AMDP methods usually contains an
|
||||
input parameter for the client ID. See more information
|
||||
[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenamdp_client_handling.htm) (or [here for the F1 docu for standard ABAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenamdp_client_handling.htm)).
|
||||
The client handling is not dealt with in this cheat sheet and not
|
||||
relevant in the executable example.
|
||||
> **✔️ Hint**<br>
|
||||
> Checking if AMDP is supported on the system:
|
||||
> ```abap
|
||||
> IF NOT cl_abap_dbfeatures=>use_features(
|
||||
> EXPORTING requested_features =
|
||||
> VALUE #( ( cl_abap_dbfeatures=>call_amdp_method ) ) ).
|
||||
>
|
||||
> "Result: Current database system does not support AMDP procedures
|
||||
> RETURN.
|
||||
> ENDIF.
|
||||
> ```
|
||||
|
||||
<p align="right"><a href="#top">⬆️ back to top</a></p>
|
||||
|
||||
@@ -442,10 +413,9 @@ relevant in the executable example.
|
||||
[zcl_demo_abap_amdp](./src/zcl_demo_abap_amdp.clas.abap)
|
||||
|
||||
> **💡 Note**<br>
|
||||
> - The executable example ...
|
||||
> - covers the following topics:
|
||||
> - AMDP procedures, calling AMDP procedures from SQLScript
|
||||
> - AMDP table functions for AMDP methods
|
||||
> - AMDP table functions for CDS table functions
|
||||
> - The executable example covers the following topics:
|
||||
> - AMDP procedures, calling AMDP procedures from SQLScript
|
||||
> - AMDP table functions for AMDP methods
|
||||
> - AMDP table functions for CDS table functions
|
||||
> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
|
||||
> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
|
||||
@@ -59,17 +59,17 @@ CLASS zcl_demo_abap_amdp DEFINITION
|
||||
|
||||
"Various internal table type specifications for the parameters of AMDP methods
|
||||
"Note: Only table and elementary data types are possible for the parameters.
|
||||
TYPES carr_tab TYPE STANDARD TABLE OF zdemo_abap_carr WITH EMPTY KEY.
|
||||
TYPES carr_tab TYPE STANDARD TABLE OF zdemo_abap_carr_ve WITH EMPTY KEY.
|
||||
|
||||
TYPES fli_tab TYPE STANDARD TABLE OF zdemo_abap_fli WITH EMPTY KEY.
|
||||
TYPES fli_tab TYPE STANDARD TABLE OF zdemo_abap_fli_ve WITH EMPTY KEY.
|
||||
|
||||
TYPES:
|
||||
"Structured data type as basis for the table type below
|
||||
BEGIN OF carr_fli_struc,
|
||||
carrname TYPE zdemo_abap_carr-carrname,
|
||||
connid TYPE zdemo_abap_flsch-connid,
|
||||
cityfrom TYPE zdemo_abap_flsch-cityfrom,
|
||||
cityto TYPE zdemo_abap_flsch-cityto,
|
||||
carrname TYPE zdemo_abap_carr_ve-carrname,
|
||||
connid TYPE zdemo_abap_flsch_ve-connid,
|
||||
cityfrom TYPE zdemo_abap_flsch_ve-cityfrom,
|
||||
cityto TYPE zdemo_abap_flsch_ve-cityto,
|
||||
END OF carr_fli_struc,
|
||||
|
||||
"Internal table type
|
||||
@@ -77,15 +77,15 @@ CLASS zcl_demo_abap_amdp DEFINITION
|
||||
|
||||
"Structured data type as basis for the table type below
|
||||
BEGIN OF fli_struc,
|
||||
carrid TYPE zdemo_abap_flsch-carrid,
|
||||
connid TYPE zdemo_abap_flsch-connid,
|
||||
cityfrom TYPE zdemo_abap_flsch-cityfrom,
|
||||
cityto TYPE zdemo_abap_flsch-cityto,
|
||||
fltime TYPE zdemo_abap_flsch-fltime,
|
||||
carrid TYPE zdemo_abap_flsch_ve-carrid,
|
||||
connid TYPE zdemo_abap_flsch_ve-connid,
|
||||
cityfrom TYPE zdemo_abap_flsch_ve-cityfrom,
|
||||
cityto TYPE zdemo_abap_flsch_ve-cityto,
|
||||
fltime TYPE zdemo_abap_flsch_ve-fltime,
|
||||
END OF fli_struc,
|
||||
|
||||
"Internal table type
|
||||
flsch_tab TYPE STANDARD TABLE OF zdemo_abap_flsch WITH EMPTY KEY.
|
||||
flsch_tab TYPE STANDARD TABLE OF zdemo_abap_flsch_ve WITH EMPTY KEY.
|
||||
|
||||
"Various instance method declarations
|
||||
"The selection for instance and static methods is irrelevant for the example.
|
||||
@@ -96,6 +96,7 @@ CLASS zcl_demo_abap_amdp DEFINITION
|
||||
"Note the parameter declaration that includes the mandatory passing by value.
|
||||
"This is true for all of the AMDP method declarations.
|
||||
METHODS select_carriers
|
||||
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT dependent
|
||||
EXPORTING VALUE(carr_tab) TYPE carr_tab.
|
||||
|
||||
"AMDP procedure to call an AMDP table function
|
||||
@@ -103,7 +104,8 @@ CLASS zcl_demo_abap_amdp DEFINITION
|
||||
"AMDP table function get_carr_fli. AMDP table functions can only be called
|
||||
"by other AMDP methods.
|
||||
METHODS select_get_carr_fli
|
||||
IMPORTING VALUE(carrid) TYPE zdemo_abap_fli-carrid
|
||||
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT dependent
|
||||
IMPORTING VALUE(carrid) TYPE zdemo_abap_fli_ve-carrid
|
||||
EXPORTING VALUE(carr_fli_tab) TYPE carr_fli_tab.
|
||||
|
||||
"Various static method declarations
|
||||
@@ -118,7 +120,8 @@ CLASS zcl_demo_abap_amdp DEFINITION
|
||||
"in the same AMDP class. The method declaration includes the addition RAISING with an
|
||||
"exception class for AMDP-specific exceptions.
|
||||
CLASS-METHODS get_flights
|
||||
IMPORTING VALUE(carrid) TYPE zdemo_abap_fli-carrid
|
||||
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT dependent
|
||||
IMPORTING VALUE(carrid) TYPE zdemo_abap_fli_ve-carrid
|
||||
EXPORTING VALUE(fli_tab) TYPE fli_tab
|
||||
RAISING cx_amdp_execution_error.
|
||||
|
||||
@@ -134,7 +137,8 @@ CLASS zcl_demo_abap_amdp DEFINITION
|
||||
"AMDP procedure
|
||||
"This method demonstrates the calling of an AMDP procedure from SQLScript as mentioned above.
|
||||
CLASS-METHODS get_flights_amdp
|
||||
IMPORTING VALUE(carrid) TYPE zdemo_abap_fli-carrid
|
||||
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT dependent
|
||||
IMPORTING VALUE(carrid) TYPE zdemo_abap_fli_ve-carrid
|
||||
EXPORTING VALUE(fli_tab) TYPE fli_tab
|
||||
RAISING cx_amdp_execution_error.
|
||||
|
||||
@@ -142,15 +146,16 @@ CLASS zcl_demo_abap_amdp DEFINITION
|
||||
"AMDP table functions can only be called by other AMDP methods. In this example,
|
||||
"the AMDP procedure select_get_carr_fli calls this AMDP table function.
|
||||
METHODS get_carr_fli
|
||||
IMPORTING VALUE(carrid) TYPE zdemo_abap_flsch-carrid
|
||||
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT dependent
|
||||
IMPORTING VALUE(carrid) TYPE zdemo_abap_flsch_ve-carrid
|
||||
RETURNING VALUE(carr_fli_tab) TYPE carr_fli_tab.
|
||||
|
||||
CONSTANTS nl TYPE string value cl_abap_char_utilities=>newline.
|
||||
CONSTANTS nl TYPE string VALUE cl_abap_char_utilities=>newline.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
|
||||
CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
CLASS zcl_demo_abap_amdp IMPLEMENTATION.
|
||||
|
||||
|
||||
METHOD class_constructor.
|
||||
@@ -164,26 +169,26 @@ CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
FOR HDB
|
||||
LANGUAGE SQLSCRIPT
|
||||
OPTIONS READ-ONLY
|
||||
USING zdemo_abap_flsch "Two database tables are used and must both be specified here.
|
||||
zdemo_abap_carr.
|
||||
* Reading data from two database tables
|
||||
USING zdemo_abap_flsch_ve
|
||||
zdemo_abap_carr_ve.
|
||||
* Reading data from two CDS view entities
|
||||
itab_cities =
|
||||
select DISTINCT
|
||||
zdemo_abap_flsch.mandt as client,
|
||||
zdemo_abap_flsch.carrid as carrier_id,
|
||||
zdemo_abap_flsch.airpfrom as airport_from,
|
||||
zdemo_abap_flsch.airpto as airport_to,
|
||||
zdemo_abap_flsch.fltime as flight_time,
|
||||
zdemo_abap_flsch.distance as flight_distance,
|
||||
zdemo_abap_flsch.distid as unit
|
||||
from zdemo_abap_flsch;
|
||||
zdemo_abap_flsch_ve.mandt as client,
|
||||
zdemo_abap_flsch_ve.carrid as carrier_id,
|
||||
zdemo_abap_flsch_ve.airpfrom as airport_from,
|
||||
zdemo_abap_flsch_ve.airpto as airport_to,
|
||||
zdemo_abap_flsch_ve.fltime as flight_time,
|
||||
zdemo_abap_flsch_ve.distance as flight_distance,
|
||||
zdemo_abap_flsch_ve.distid as unit
|
||||
from zdemo_abap_flsch_ve;
|
||||
|
||||
itab_carrier_names =
|
||||
select distinct
|
||||
zdemo_abap_carr.mandt as client,
|
||||
zdemo_abap_carr.carrid as carrier_id,
|
||||
zdemo_abap_carr.carrname as carrier_name
|
||||
from zdemo_abap_carr;
|
||||
zdemo_abap_carr_ve.mandt as client,
|
||||
zdemo_abap_carr_ve.carrid as carrier_id,
|
||||
zdemo_abap_carr_ve.carrname as carrier_name
|
||||
from zdemo_abap_carr_ve;
|
||||
|
||||
* Returning joined data using an inner join
|
||||
return
|
||||
@@ -211,13 +216,13 @@ CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
FOR HDB
|
||||
LANGUAGE SQLSCRIPT
|
||||
OPTIONS READ-ONLY
|
||||
USING zdemo_abap_carr zdemo_abap_flsch.
|
||||
USING zdemo_abap_carr_ve zdemo_abap_flsch_ve.
|
||||
* AMDP table function to be called by other AMDP methods only.
|
||||
* In the example, joined data from two database table are returned.
|
||||
* In the example, joined data from two CDS view entities are returned.
|
||||
RETURN
|
||||
SELECT ca.carrname, fl.connid, fl.cityfrom, fl.cityto
|
||||
FROM zdemo_abap_carr as ca
|
||||
INNER JOIN zdemo_abap_flsch as fl
|
||||
FROM zdemo_abap_carr_ve as ca
|
||||
INNER JOIN zdemo_abap_flsch_ve as fl
|
||||
ON ca.carrid = fl.carrid
|
||||
WHERE fl.carrid = :carrid
|
||||
ORDER BY ca.mandt, ca.carrname, fl.connid;
|
||||
@@ -242,10 +247,12 @@ CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
FOR HDB
|
||||
LANGUAGE SQLSCRIPT
|
||||
OPTIONS READ-ONLY
|
||||
USING zdemo_abap_fli.
|
||||
USING zdemo_abap_fli_ve.
|
||||
* Simple data selection
|
||||
fli_tab = SELECT *
|
||||
FROM "ZDEMO_ABAP_FLI"
|
||||
fli_tab = SELECT carrid, connid, fldate, price, currency, planetype,
|
||||
seatsmax, seatsocc, paymentsum, seatsmax_b, seatsocc_b,
|
||||
seatsmax_f, seatsocc_f
|
||||
FROM "ZDEMO_ABAP_FLI_VE"
|
||||
WHERE carrid = :carrid
|
||||
ORDER BY carrid;
|
||||
ENDMETHOD.
|
||||
@@ -253,7 +260,7 @@ CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
|
||||
METHOD if_oo_adt_classrun~main.
|
||||
|
||||
out->write( `ABAP Cheat Sheet Example: ABAP AMDP` ).
|
||||
out->write( `ABAP Cheat Sheet Example: AMDP` ).
|
||||
|
||||
out->write( |\n1) AMDP Procedure\n\n| ).
|
||||
|
||||
@@ -279,17 +286,13 @@ CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
"As can be seen in the method implementation part, this AMDP procedure
|
||||
"includes an AMDP procedure call from SQLScript.
|
||||
"In this example, the AMDP procedure get_flights_amdp is called by
|
||||
"get_flights which is meant to select data from a database table.
|
||||
"get_flights which is meant to select data from a CDS view entity.
|
||||
"The returned result is displayed.
|
||||
TRY.
|
||||
|
||||
zcl_demo_abap_amdp=>get_flights( EXPORTING carrid = 'LH'
|
||||
IMPORTING fli_tab = DATA(call_amdp_res) ).
|
||||
|
||||
CATCH cx_amdp_execution_error INTO DATA(error1).
|
||||
|
||||
out->write( error1->get_text( ) ).
|
||||
|
||||
ENDTRY.
|
||||
|
||||
out->write( data = call_amdp_res name = `call_amdp_res` ).
|
||||
@@ -303,15 +306,11 @@ CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
"get_carr_fli in the implementation part. AMDP table functions can
|
||||
"only be called by other AMDP methods.
|
||||
TRY.
|
||||
|
||||
NEW zcl_demo_abap_amdp( )->select_get_carr_fli(
|
||||
EXPORTING carrid = 'LH'
|
||||
IMPORTING carr_fli_tab = DATA(amdp_tab_func) ).
|
||||
|
||||
CATCH cx_amdp_execution_error INTO DATA(error2).
|
||||
|
||||
out->write( error2->get_text( ) ).
|
||||
|
||||
ENDTRY.
|
||||
|
||||
out->write( data = amdp_tab_func name = `amdp_tab_func` ).
|
||||
@@ -333,7 +332,7 @@ CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
"In this example, the CDS table function is implemented in a way to
|
||||
"return accumulated data.
|
||||
"In the method implementation for flight_analysis, first two kinds of
|
||||
"data sets from two database tables are gathered. These data sets are
|
||||
"data sets from two CDS view entities are gathered. These data sets are
|
||||
"joined using an inner join. There, some expressions are included
|
||||
"(strings are aggregated, average values are determined).
|
||||
|
||||
@@ -350,10 +349,10 @@ CLASS ZCL_DEMO_ABAP_AMDP IMPLEMENTATION.
|
||||
FOR HDB
|
||||
LANGUAGE SQLSCRIPT
|
||||
OPTIONS READ-ONLY
|
||||
USING zdemo_abap_carr.
|
||||
USING zdemo_abap_carr_ve.
|
||||
* Simple data selection
|
||||
carr_tab = SELECT *
|
||||
FROM "ZDEMO_ABAP_CARR"
|
||||
carr_tab = SELECT carrid, carrname, currcode, url
|
||||
FROM "ZDEMO_ABAP_CARR_VE"
|
||||
ORDER BY carrid;
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
9
src/zdemo_abap_carr_ve.ddls.asddls
Normal file
9
src/zdemo_abap_carr_ve.ddls.asddls
Normal file
@@ -0,0 +1,9 @@
|
||||
@AccessControl.authorizationCheck: #NOT_REQUIRED
|
||||
define view entity ZDEMO_ABAP_CARR_VE
|
||||
as select from zdemo_abap_carr
|
||||
{
|
||||
key carrid,
|
||||
carrname,
|
||||
currcode,
|
||||
url
|
||||
}
|
||||
19
src/zdemo_abap_carr_ve.ddls.baseinfo
Normal file
19
src/zdemo_abap_carr_ve.ddls.baseinfo
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"BASEINFO":
|
||||
{
|
||||
"FROM":
|
||||
[
|
||||
"ZDEMO_ABAP_CARR"
|
||||
],
|
||||
"ASSOCIATED":
|
||||
[],
|
||||
"BASE":
|
||||
[],
|
||||
"ANNO_REF":
|
||||
[],
|
||||
"SCALAR_FUNCTION":
|
||||
[],
|
||||
"VERSION":0,
|
||||
"ANNOREF_EVALUATION_ERROR":""
|
||||
}
|
||||
}
|
||||
13
src/zdemo_abap_carr_ve.ddls.xml
Normal file
13
src/zdemo_abap_carr_ve.ddls.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DDLS" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<DDLS>
|
||||
<DDLNAME>ZDEMO_ABAP_CARR_VE</DDLNAME>
|
||||
<DDLANGUAGE>E</DDLANGUAGE>
|
||||
<DDTEXT>Demo CDS view entity</DDTEXT>
|
||||
<SOURCE_TYPE>W</SOURCE_TYPE>
|
||||
</DDLS>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
||||
18
src/zdemo_abap_fli_ve.ddls.asddls
Normal file
18
src/zdemo_abap_fli_ve.ddls.asddls
Normal file
@@ -0,0 +1,18 @@
|
||||
@AccessControl.authorizationCheck: #NOT_REQUIRED
|
||||
define view entity ZDEMO_ABAP_FLI_VE
|
||||
as select from zdemo_abap_fli
|
||||
{
|
||||
key carrid,
|
||||
key connid,
|
||||
key fldate,
|
||||
price,
|
||||
currency,
|
||||
planetype,
|
||||
seatsmax,
|
||||
seatsocc,
|
||||
paymentsum,
|
||||
seatsmax_b,
|
||||
seatsocc_b,
|
||||
seatsmax_f,
|
||||
seatsocc_f
|
||||
}
|
||||
19
src/zdemo_abap_fli_ve.ddls.baseinfo
Normal file
19
src/zdemo_abap_fli_ve.ddls.baseinfo
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"BASEINFO":
|
||||
{
|
||||
"FROM":
|
||||
[
|
||||
"ZDEMO_ABAP_FLI"
|
||||
],
|
||||
"ASSOCIATED":
|
||||
[],
|
||||
"BASE":
|
||||
[],
|
||||
"ANNO_REF":
|
||||
[],
|
||||
"SCALAR_FUNCTION":
|
||||
[],
|
||||
"VERSION":0,
|
||||
"ANNOREF_EVALUATION_ERROR":""
|
||||
}
|
||||
}
|
||||
13
src/zdemo_abap_fli_ve.ddls.xml
Normal file
13
src/zdemo_abap_fli_ve.ddls.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DDLS" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<DDLS>
|
||||
<DDLNAME>ZDEMO_ABAP_FLI_VE</DDLNAME>
|
||||
<DDLANGUAGE>E</DDLANGUAGE>
|
||||
<DDTEXT>Demo CDS view entity</DDTEXT>
|
||||
<SOURCE_TYPE>W</SOURCE_TYPE>
|
||||
</DDLS>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
||||
20
src/zdemo_abap_flsch_ve.ddls.asddls
Normal file
20
src/zdemo_abap_flsch_ve.ddls.asddls
Normal file
@@ -0,0 +1,20 @@
|
||||
@AccessControl.authorizationCheck: #NOT_REQUIRED
|
||||
define view entity ZDEMO_ABAP_FLSCH_VE
|
||||
as select from zdemo_abap_flsch
|
||||
{
|
||||
key carrid,
|
||||
key connid,
|
||||
countryfr,
|
||||
cityfrom,
|
||||
airpfrom,
|
||||
countryto,
|
||||
cityto,
|
||||
airpto,
|
||||
fltime,
|
||||
deptime,
|
||||
arrtime,
|
||||
distance,
|
||||
distid,
|
||||
fltype,
|
||||
period
|
||||
}
|
||||
19
src/zdemo_abap_flsch_ve.ddls.baseinfo
Normal file
19
src/zdemo_abap_flsch_ve.ddls.baseinfo
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"BASEINFO":
|
||||
{
|
||||
"FROM":
|
||||
[
|
||||
"ZDEMO_ABAP_FLSCH"
|
||||
],
|
||||
"ASSOCIATED":
|
||||
[],
|
||||
"BASE":
|
||||
[],
|
||||
"ANNO_REF":
|
||||
[],
|
||||
"SCALAR_FUNCTION":
|
||||
[],
|
||||
"VERSION":0,
|
||||
"ANNOREF_EVALUATION_ERROR":""
|
||||
}
|
||||
}
|
||||
13
src/zdemo_abap_flsch_ve.ddls.xml
Normal file
13
src/zdemo_abap_flsch_ve.ddls.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DDLS" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<DDLS>
|
||||
<DDLNAME>ZDEMO_ABAP_FLSCH_VE</DDLNAME>
|
||||
<DDLANGUAGE>E</DDLANGUAGE>
|
||||
<DDTEXT>Demo CDS view entity</DDTEXT>
|
||||
<SOURCE_TYPE>W</SOURCE_TYPE>
|
||||
</DDLS>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
||||
@@ -1,4 +1,6 @@
|
||||
@AccessControl.authorizationCheck: #NOT_REQUIRED
|
||||
@ClientHandling.type: #CLIENT_DEPENDENT
|
||||
@ClientHandling.algorithm: #SESSION_VARIABLE
|
||||
define table function ZDEMO_ABAP_TABLE_FUNCTION
|
||||
returns
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user