**ECC &HANA之FICO异同 **
**问**
尽管S4 HANA从发布以来已经过去很久,但目前仍有部分客户使用的仍是ECC系统。
那么两个系统在FICO模块中有哪些常见的不同呢?
以下内容整理自 SAP 官方 ABAP 速查表(主题:ABAP Managed Database Procedures),作为本文的扩展补充资料。
This cheat sheet gathers basic information on ABAP Managed Database Procedures (AMDP). Find more details here in the ABAP Keyword Documentation.
procedures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_procedure_glosry.htm "Glossary Entry") (which is a synonym for stored procedures, i. e. the procedures are stored in the database - the SAP HANA database in this case - and executed there)
functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_function_glosry.htm "Glossary Entry") (which are SQLScript functions in the SAP HANA database)
in AS ABAP.
implementing special AMDP procedures as database procedures and AMDP functions as database functions.
language. Currently, AMDP only supports database procedures and functions from the SAP HANA database. That is, SQLScript is the programming language of choice.
class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenamdp_class_glosry.htm "Glossary Entry") and declared and implemented as part of a method. The classes and methods have certain characteristics as outlined further down.
database system, i. e. despite the fact that the programming happens in an AMDP class (which is an ABAP Repository object as other global classes, too), the (SQLScript) code is executed only on the (SAP HANA) database and not in AS ABAP, i. e. method calls are sent to the database procedure or function.
[!NOTE] - The use of AMDP is not recommended if the same task can be
achieved using ABAP SQL.
- AMDP classes can only be edited with the [ABAP development tools for Eclipse
(ADT)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenadt_glosry.htm "Glossary Entry").
is an ABAP repository object like other global classes.
IF_AMDP_MARKER_HDB for the SAP HANA database (indicated by HDB), which is currently the only possible database.
methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenamdp_method_glosry.htm "Glossary Entry") and non-AMDP methods.
Example for a declaration part of an AMDP class:
CLASS cl_some_amdp_class DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
"Specifying the interface is mandatory
INTERFACES if_amdp_marker_hdb.
...
ENDCLASS.methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_method_glosry.htm "Glossary Entry") using METHODS or static methods using CLASS-METHODS in any visibility section.
class since there are no specific additions to the methods. Exceptions: AMDP function implementations that implement any CDS table functions as shown further down and method declarations using AMDP OPTIONS that are not dealt with here.
AMDP method declarations in any visibility section like non-AMDP methods:
...
PUBLIC SECTION.
METHODS some_amdp_meth
... "Here go the parameters
PRIVATE SECTION.
CLASS-METHODS another_amdp_meth
... "Here go the parameters
...Despite the fact that AMDP methods cannot be identified as such from the declaration part (apart from the exceptions mentioned above), the declaration part of AMDP procedures has special characteristics:
value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpass_by_value_glosry.htm "Glossary Entry") using VALUE(...). Passing by reference is not allowed.
types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_type_glosry.htm "Glossary Entry") and table types with a structured row type (and this type can only contain elementary data types as components).
RETURNING.Example for an AMDP procedure's declaration part:
...
PUBLIC SECTION.
"Table type with a structured row type
TYPES tab_type TYPE STANDARD TABLE OF dbtab WITH EMPTY KEY.
METHODS amdp_meth
IMPORTING VALUE(num) TYPE i,
EXPORTING VALUE(tab) TYPE tab_type.
...In contrast to the declaration part, the implementation part of an AMDP method has multiple special additions for AMDP purposes following METHOD and the method name:
...
METHOD amdp_meth
BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING db_object. "see comments further down
"Beginning of the SQLScript code (note that it is not ABAP code although it looks similar)
... "Here goes SQLScript code
"Note that an AMDP method implementation must not be empty.
"End of the SQLScript code
ENDMETHOD.
...
"Comments:
" BY DATABASE PROCEDURE -> Flags the AMDP method as AMDP procedure
" FOR HDB -> Definess the database system where the method is to be used;
" currently, only HDB (SAP HANA database) is possible
" LANGUAGE SQLSCRIPT -> Defines the programming language of the database system
" OPTIONS READ-ONLY -> Specifies database-specific options
" USING db_object. -> Optional addition; specifies database objects;
" can also be AMDP procedures and functionsNote:
scope), only reads are allowed. Hence, the addition OPTIONS READ-ONLY is mandatory. Furthermore, you must make sure that the database objects that are specified after USING are accessible.
version](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunrestricted_version_glosry.htm "Glossary Entry") scope), more syntax options are allowed for AMDP method declaration and implementation parts. Check the ABAP Keyword Documentation for more details as covered further down.
Scalar and table functions can be managed as AMDP functions. AMDP table functions, as the name suggests, have a tabular return value, while AMDP scalar functions have a scalar (i.e. an elementary) return value. These functions allow complex custom calculations to be executed directly on the SAP HANA database to boost performance, enhancing performance and enabling reuse.
Two kinds of AMDP table functions are available:
Characteristics of method declaration parts of AMDP table functions for AMDP methods:
RETURNING and having a tabular data type.RAISING.Example of an AMDP table function's declaration part:
...
PUBLIC SECTION.
"Table type with a structured row type
TYPES tab_type TYPE STANDARD TABLE OF dbtab WITH EMPTY KEY.
METHODS amdp_func
IMPORTING VALUE(num) TYPE i,
VALUE(some_elem) TYPE c LENGTH 3,
RETURNING VALUE(tab) TYPE tab_type.
...The implementation part of an AMDP function is similar to the one of AMDP procedures as shown above. The difference is the use of BY DATABASE FUNCTION instead of BY DATABASE PROCEDURE:
...
METHOD amdp_func
BY DATABASE FUNCTION "<- Flags the AMDP method as AMDP function
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING db_object.
*Beginning of the SQLScript code (note that it is not ABAP code)
*Here goes SQLScript code
*AMDP table function to be called by other AMDP methods only
...
*End of the SQLScript code
ENDMETHOD.
...CLASS-METHODS.FOR TABLE FUNCTION.is not specified. Instead, the input parameters are determined by the input parameters of the CDS table function (i. e. the names and data types - which are always elementary - specified there are used). As the return value, a standard table with an empty key is generated based on the structured row type including the components as specified in the CDS table function.
Using AMDP table functions for CDS table functions
To use CDS table functions, you need these development objects:
define table functionCLASS-METHODS table_func FOR TABLE FUNCTION some_ddl_source.SELECT statements, for example: SELECT * FROM some_ddl_source INTO .... Furthermore, CDS table functions represent globally available structured types (but they are not usable for typing in the ABAP Dictionary).Notes on the syntax to create CDS table functions
Example:
//Here go annotations.
define table function some_ddl_source
with parameters
param : abap.char(3)
returns
{
client : abap.clnt;
field1 : abap.char(5);
field2 : abap.int4;
}
implemented by method amdp_class=>amdp_method;define table function.... with parameters parameter1, parameter2, ... in a comma-separated list. Elementary data types are expected.... returns { element1; element2; ...; } .... The elements - elementary data types are expected - are separated by semicolons and determine the components of the structured data type of the tabular return value. The syntax allows to specify key elements using the key addition. Find more information here.implemented by method addition followed by a fully qualified method name in the form of amdp_class=>amdp_method using the names of the AMDP class and method.Two kinds of AMDP scalar functions are available:
The characteristics of method declaration parts of AMDP scalar functions for AMDP methods are similar to AMDP table functions. Among the differences are:
[!NOTE] The executable example in the AMDP Scalar Functions for CDS Scalar Functions section includes AMDP scalar functions for AMDP methods.
CLASS-METHODS.FOR SCALAR FUNCTION.ON or WHERE condition and others, are possible[!NOTE] - CDS scalar functions are available as analytical scalar functions and SQL-based scalar functions, i.e. they are either evalauted by an SQL environment or an analytical runtime environment. - The example below focuses on SQL-based scalar functions. Analytical scalar functions are predelivered system functions and cannot be user-defined. Find more information here.
Using AMDP scalar functions for CDS scalar functions
To use CDS scalar functions, you need these three development objects:
define scalar functionCLASS-METHODS some_meth FOR SCALAR FUNCTION some_cds_scalar_func. Notes on the syntax to create CDS scalar functions
Example:
define scalar function zdemo_abap_scalar_func
with parameters
// Built-in DDIC types
param1 : abap.char(3),
param2 : abap.decfloat34,
param3 : abap.int4,
// DDIC data elements
param4 : abap_boolean,
param5 : land1,
// CDS simple types
param6 : calendar_fiscal_operation,
// Generic types
param7 : numeric,
param8 : any,
// Referencing types from input parameters
param9 : type of param1,
param10: type of param2,
// Specifying a reference to a currency key,
// unit key, calculated unit, or none of them
param11: numeric
with reference type [ #CUKY ],
param12: numeric
with reference type [ #CUKY, #UNIT, #CALC ],
param13: numeric
with reference type [ #NONE ],
// Mandatory reference to unit key and unit key
param14: abap.quan(8,2)
with reference type [ #UNIT ],
param15: abap.curr(8,2)
with reference type [ #CUKY ]
returns abap.dec(8,2)with parameter in a comma-separated list, TYPE OF some_inp_param: some_inp_param can be the name of any input parameter from the list, and that does not reference a type itselfany and numericwith reference type addition: #CUKY), a unit key (#UNIT), or a calculated unit (#CALC), or none of them (#NONE); for some types such as abap.quan and abap.curr, the reference type is required case statement; find more information hereThe following example includes the creation of the three required artifacts (CDS scalar function, CDS scalar function implementation reference, AMDP class including an AMDP scalar function for CDS scalar function, as well as an AMDP scalar function for AMDP method). The AMDP class implements the if_oo_adt_classrun interface, making the class executable. The simplified example illustrates AMDP scalar functions at a high level. After activating all artifacts, choose F9 in ADT to run the class. The example is set up to display output in the console.
[!NOTE] As a prerequisite for exploring the example, you have imported the ABAP cheat sheet repository as the example uses some of its artifacts.
🟢 Click to expand for implementation steps and example code
Create a CDS scalar function definition
zdemo_abap_scalar_func, and select the defineScalarFunction template.define scalar function zdemo_abap_scalar_func
with parameters
num : numeric,
total : type of num
returns abap.dec( 8, 2 )Create a scalar function implementation reference
zdemo_abap_scalar_func_sql. Note that the name must be identical to the CDS scalar function plus the suffix _sql (_ana is used for analytical scalar function).zcl_demo_abap=>execute_scalar_func.Create an AMDP class that includes an AMDP function implementing the scalar function as database function
zcl_demo_abap. If it already exists, reuse it. Otherwise, create a new class with a different name. Paste the code into it. If you choose a different class name, update the class name in the code snippet accordingly. [!NOTE] - The demo class includes multiple AMDP methods demonstrating several aspects regarding AMDP scalar functions: -get_max_fltimedemonstrates an AMDP scalar function for AMDP method. It returns the longest flight time among all flights of a certain carrier. -select_entries_w_max_fltimedemonstrates an AMDP procedure that includes calling theget_max_fltimeAMDP scalar function. The effect is the same as shown with an ABAP SQLSELECTstatement usingget_max_fltime. -execute_scalar_funcdemonstrates an AMDP scalar function for CDS scalar function. It calculates the ratio of a share to a total. - The example implementations are simplified to foucs on high-level functionality.
CLASS zcl_demo_abap DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: if_oo_adt_classrun,
if_amdp_marker_hdb.
CLASS-METHODS class_constructor.
TYPES occ_rate_type TYPE p LENGTH 8 DECIMALS 2.
"AMDP scalar function for AMDP method
METHODS get_max_fltime
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT DEPENDENT
IMPORTING VALUE(carrid) TYPE zdemo_abap_flsch_ve-carrid
RETURNING VALUE(max_fltime) TYPE zdemo_abap_flsch_ve-fltime.
"AMDP procedure whose implementation includes calling an AMDP scalar function
TYPES: BEGIN OF flight_struc_type,
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 flight_struc_type,
flight_tab_type TYPE TABLE OF flight_struc_type WITH EMPTY KEY.
METHODS select_entries_w_max_fltime
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT DEPENDENT
IMPORTING VALUE(carrid) TYPE zdemo_abap_flsch_ve-carrid
EXPORTING VALUE(flight_tab) TYPE flight_tab_type.
"AMDP scalar function for CDS scalar function
CLASS-METHODS execute_scalar_func FOR SCALAR FUNCTION zdemo_abap_scalar_func.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_demo_abap IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
*&---------------------------------------------------------------------*
*& AMDP function implementation for an AMDP scalar function
*&---------------------------------------------------------------------*
out->write( |AMDP function implementation for an AMDP scalar function\n\n| ).
DATA(oref) = NEW zcl_demo_abap( ).
DATA(max_fltime_lh) = oref->get_max_fltime( carrid = 'LH' ).
out->write( max_fltime_lh ).
DATA(max_fltime_az) = oref->get_max_fltime( carrid = 'AZ' ).
out->write( max_fltime_az ).
DATA(max_fltime_dl) = oref->get_max_fltime( carrid = 'DL' ).
out->write( max_fltime_dl ).
out->write( |\n{ repeat( val = `*` occ = 100 ) }\n| ).
*&---------------------------------------------------------------------*
*& AMDP function implementation for an AMDP scalar function in ABAP SQL
*&---------------------------------------------------------------------*
out->write( |AMDP function implementation for an AMDP scalar function in ABAP SQL\n\n| ).
DATA carrid_tab TYPE TABLE OF zdemo_abap_flsch_ve-carrid WITH EMPTY KEY.
carrid_tab = VALUE #( ( 'LH' ) ( 'AZ' ) ( 'DL' ) ).
LOOP AT carrid_tab INTO DATA(carrid).
SELECT carrid, connid, cityfrom, cityto, fltime
FROM zdemo_abap_flsch_ve
WHERE carrid = @carrid AND
fltime = @( NEW zcl_demo_abap( )->get_max_fltime( carrid = carrid ) )
INTO TABLE @DATA(selection_result).
out->write( selection_result ).
out->write( |\n\n| ).
ENDLOOP.
out->write( |\n{ repeat( val = `*` occ = 100 ) }\n| ).
*&---------------------------------------------------------------------*
*& AMDP procedure whose implementation includes calling an AMDP scalar
*& function
*&---------------------------------------------------------------------*
out->write( |AMDP procedure whose implementation includes calling an AMDP scalar function\n\n| ).
LOOP AT carrid_tab INTO carrid.
NEW zcl_demo_abap( )->select_entries_w_max_fltime(
EXPORTING carrid = carrid
IMPORTING flight_tab = DATA(flights) ).
out->write( flights ).
out->write( |\n\n| ).
ENDLOOP.
out->write( |\n{ repeat( val = `*` occ = 100 ) }\n| ).
*&---------------------------------------------------------------------*
*& AMDP scalar function for CDS scalar function
*&---------------------------------------------------------------------*
out->write( |AMDP scalar function for CDS scalar function\n\n| ).
MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #(
( key_field = 1 num1 = 3 num2 = 10 )
( key_field = 2 num1 = 12 num2 = 123 )
( key_field = 3 num1 = 5 num2 = 39 )
( key_field = 4 num1 = 98 num2 = 9876 ) ) ).
SELECT FROM zdemo_abap_tab1
FIELDS key_field, num1, num2,
zdemo_abap_scalar_func(
num = num1,
total = num2 ) AS rate
ORDER BY key_field
INTO TABLE @DATA(res_dbtab).
out->write( res_dbtab ).
out->write( |\n{ repeat( val = `*` occ = 100 ) }\n\n| ).
"Selecting from the demo CDS view entity that uses the
"AMDP scalar function
"Comment in the code if you have created the CDS view entity.
* SELECT FROM zdemo_abap_cds_ve_w_scalar
* FIELDS *
* ORDER BY carrid
* INTO TABLE @DATA(res_cds_ve)
* UP TO 15 ROWS.
*
* out->write( res_cds_ve ).
ENDMETHOD.
METHOD select_entries_w_max_fltime BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING zdemo_abap_flsch_ve
zcl_demo_abap=>get_max_fltime.
flight_tab = select carrid, connid, cityfrom, cityto, fltime
from zdemo_abap_flsch_ve
where fltime = "ZCL_DEMO_ABAP=>GET_MAX_FLTIME"( carrid => :carrid );
ENDMETHOD.
METHOD execute_scalar_func BY DATABASE FUNCTION
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY.
result = num / total * 100;
ENDMETHOD.
METHOD get_max_fltime BY DATABASE FUNCTION
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING zdemo_abap_flsch_ve.
SELECT MAX(fltime)
INTO max_fltime
FROM zdemo_abap_flsch_ve
WHERE carrid = :carrid;
ENDMETHOD.
METHOD class_constructor.
"Preparing demo data
zcl_demo_abap_aux=>fill_dbtabs( ).
MODIFY zdemo_abap_flsch FROM TABLE @( VALUE #(
( carrid = 'AZ'
connid = 0799
countryfr = 'JP'
cityfrom = 'TOKYO'
airpfrom = 'TYO'
countryto = 'IT'
cityto = 'ROME'
airpto = 'FCO'
fltime = 940
deptime = '124500'
arrtime = '202500'
distance = 6130
distid = 'MI'
fltype = ''
period = 0 )
( carrid = 'DL'
connid = 0199
countryfr = 'US'
cityfrom = 'NEW YORK'
airpfrom = 'JFK'
countryto = 'DE'
cityto = 'FRANKFURT'
airpto = 'FRA'
fltime = 475
deptime = '203500'
arrtime = '103000'
distance = 3851
distid = 'MI'
fltype = ''
period = 1 )
( carrid = 'LH'
connid = 0499
countryfr = 'DE'
cityfrom = 'FRANKFURT'
airpfrom = 'FRA'
countryto = 'US'
cityto = 'NEW YORK'
airpto = 'JFK'
fltime = 455
deptime = '123000'
arrtime = '140500'
distance = 6162
distid = 'KM'
fltype = 'X'
period = 0 ) ) ).
DELETE FROM zdemo_abap_tab1.
ENDMETHOD.
ENDCLASS.**Excursion: Create a CDS view entity that uses the *AMDP scalar function for CDS scalar function***
zdemo_abap_cds_ve_w_scalar for the CDS view entity.F8 to open the data preview. You can check the data after running the example class from above that populates the underlying database table (or you have already run an ABAP cheat sheet example class, or filled the table using zcl_demo_abap_aux=>fill_dbtabs( ).). The example class above includes an ABAP SQL SELECT statement. If you have created the CDS view entity, you can comment in the code in the class.@AccessControl.authorizationCheck: #NOT_REQUIRED
define view entity zdemo_abap_cds_ve_w_scalar
as select from zdemo_abap_fli
{
key carrid,
key connid,
key fldate,
seatsmax,
seatsocc,
zdemo_abap_scalar_func(
num => seatsocc,
total => seatsmax ) as occrate
}[!IMPORTANT] - ABAP SQL features implicit client handling. - You cannot disable this feature in ABAP for Cloud Development, as you can in Standard ABAP. You can only access your own client in ABAP for Cloud Development. - Native SQL, unlike ABAP SQL, does not feature implicit client handling. AMDP, which uses Native SQL, can be used in ABAP for Cloud Development. It is essential to ensure AMDP accesses only client-safe repository objects, meaning it retrieves data solely from client-dependent sources providing data of one client, i.e. the current client. Cross-client access must be avoided. Client-independent data sources are implicitly client-safe. - Dedicated additions and annotations in the context of AMDP ensure client safety.
ABAP SQL
USING CLIENT addition to ABAP SQL statements can alter this behavior by disabling implicit client handling, however, this addition is not available in ABAP for Cloud Development.Native SQL/AMDP
USING list of AMDP methods must be client-safe, including CDS table functions implemented as AMDP methods.AMDP OPTIONS READ-ONLY in AMDP method declarations and OPTIONS READ-ONLY in AMDP method implementations.To ensure client safety, the following prerequisites must be met.
USING list:CDS SESSION CLIENT DEPENDENTUSING list that access data from the current client only.USING list:CDS_CLIENT (CDS session variable $session.client) CDS SESSION CLIENT DEPENDENT handle client safety automatically. A database view, that wraps the database table, is generated implicitly to access and select data for the client specified in the HANA session variable CDS_CLIENT, ensuring the data source is client-safe. CDS SESSION CLIENT DEPENDENT or CLIENT INDEPENDENT AMDP methodsCLIENT INDEPENDENTUSING list: Client-independent CDS view entities, DDIC database tables, client-safe CDS table functions, AMDP methods (specifying CLIENT INDEPENDENT)@ClientHandling.type: CLIENT_DEPENDENT (should be used together with the @ClientHandling.algorithm: #SESSION_VARIABLE annotation) @ClientHandling.type: #CLIENT_INDEPENDENT @Environment.systemField: #CLIENT @ClientHandling.clientSafe ensures client-dependent CDS table functions are client-safe by enforcing client-safety checks. In ABAP for Cloud Development, specifying this annotation is unnecessary as the checks are automatically enabled.USING list.[!NOTE] - Using pre-delivered repository objects in ABAP for Cloud Development: - Use only pre-delivered AMDP methods with a C4 contract. - Create and use your own wrapper CDS view entities for pre-delivered CDS view entities with a C1 contract. - More information: - The table in this topic shows an overview of specification options regarding client safety. - Client Handling in CDS Table Functions
[!TIP] Checking if AMDP is supported in classic ABAP: ``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. ``
[!NOTE] - 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 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. - The steps to import and run the code are outlined here. - Disclaimer
12_AMDP.md。版权归原作者所有。