Начиная с релиза ABAP 7.50 у нас появилась возможность создания не только AMDP процедур, но и AMDP функций. В зависимости от типа AMDP функции они могут быть вызваны:
- непосредственно из ABAP кода,
- из других AMDP методов,
- как источник данных для специальной ABAP CDS сущности называемой табличной функцией CDS.
Далее рассмотрим все варианты использования AMDP функций.
В отличие от AMDP процедур, AMDP функция реализуется как AMDP метод, но с указанием дополнения BY DATABASE FUNCTION:
1 2 3 4 5 6 7 8 9 10 |
METHOD meth BY DATABASE FUNCTION FOR db LANGUAGE db_lang [OPTIONS db_options] [USING db_entities] [USING SCHEMA schema1 OBJECTS db_entities] [USING SCHEMA schema2 OBJECTS db_entities] ... . ... ENDMETHOD. |
Существует следующие виды AMDP функций:
- AMDP табличная функция — в контексте HANA это функция БД, которая в качестве результата возвращает табличный результат. В SQLScript табличные функции могут быть использованы как источник данных вместо таблиц или ракурсов.
- AMDP табличная функция для AMDP методов.
- AMDP табличная функция для табличной функции ABAP CDS.
- AMDP скалярная функция — функция в БД, которая в качестве результата возвращает результат элементарного типа.
Несмотря на возможность вызова AMDP функций из объектов HANA Native разработки, таких как хранимые процедуры или calculation view, SAP не рекомендует так делать.
Скалярные AMDP функции
Особенности:
- Должна иметь RETURNING параметр элементарного типа.
- IMPORING параметры должны быть элементарного типа.
- Не допускается объявление исключений в определении через дополнение RAISING.
- Допускается использование дополнения DETERMINISTIC после OPTIONS — чтобы обеспечить кеширование результата функции в рамках запроса, если входные параметры вызова функции будут идентичными. Более подробно.
Допускается вызов скалярных AMDP функций непосредственно из ABAP, в т.ч. как функциональных методов.
Рассмотрим простой пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
CLASS zcl_amdp_scalar_function_demo DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb. CLASS-METHODS: get_max_payment_sum IMPORTING VALUE(iv_mandt) TYPE mandt VALUE(iv_carrid) TYPE s_carr_id VALUE(iv_connid) TYPE s_conn_id RETURNING VALUE(rv_max_payment_sum) TYPE s_sum, get_flight_with_max_sum IMPORTING VALUE(iv_carrid) TYPE s_carr_id VALUE(iv_connid) TYPE s_conn_id EXPORTING VALUE(et_flights) TYPE ty_flights. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_amdp_scalar_function_demo IMPLEMENTATION. METHOD get_max_payment_sum BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY DETERMINISTIC USING sflight. SELECT MAX( paymentsum ) INTO rv_max_payment_sum FROM sflight WHERE mandt = :iv_mandt AND carrid = :iv_carrid AND connid = :iv_connid; ENDMETHOD. METHOD get_flight_with_max_sum BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING sflight zcl_amdp_scalar_function_demo=>get_max_payment_sum. et_flights = SELECT * FROM sflight WHERE mandt = SESSION_CONTEXT('CLIENT') AND paymentsum = "ZCL_AMDP_SCALAR_FUNCTION_DEMO=>GET_MAX_PAYMENT_SUM" ( iv_mandt => SESSION_CONTEXT('CLIENT'), iv_carrid => :iv_carrid, iv_connid => :iv_connid ); ENDMETHOD. ENDCLASS. |
В данном примере мы создали скалярную функцию get_max_payment_sum, которая возвращает максимальную сумму платежей по авиакомпании и рейсу вне зависимости от даты. А внутри AMDP процедуры get_flight_with_max_sum получили записи, где paymentsum равна максимальной в разрезе авиакомпании и рейса.
Обратите внимание на опцию DETERMINISTIC, если вы её используете, вы не можете получить мандант из функции SESSION_CONTEXT( ‘CLIENT’ ).
Как уже было упомянуто ранее, такие функции могут быть вызваны из ABAP кода:
1 2 3 4 5 6 7 |
PARAMETERS: p_carrid TYPE s_carr_id, p_connid TYPE s_conn_id. START-OF-SELECTION. cl_demo_output=>display( |{ zcl_amdp_scalar_function_demo=>get_max_payment_sum( iv_mandt = sy-mandt iv_carrid = p_carrid iv_connid = p_connid ) DECIMALS = 2 }| ). |
Табличные AMDP функции
Табличная функция для AMDP методов
Особенности:
- Функция должна иметь RETURNING параметр табличного типа, все компоненты структуры которого должны иметь элементарный тип.
- Не допускается использование CHANGING или EXPORTING параметров.
- Не допускается объявление исключений в определении через дополнение RAISING.
- Обязательно должно быть указание READ-ONLY.
- Нельзя вызвать непосредственно из ABAP кода.
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
CLASS zcl_amdp_function_demo DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb. CLASS-METHODS: get_flight_with_max_sum IMPORTING VALUE(iv_carrid) TYPE s_carr_id VALUE(iv_connid) TYPE s_conn_id RETURNING VALUE(rt_flights) TYPE ty_flights. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_amdp_function_demo IMPLEMENTATION. METHOD get_flight_with_max_sum BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING sflight zcl_amdp_scalar_function_demo=>get_max_payment_sum. RETURN SELECT * FROM sflight WHERE mandt = session_context('CLIENT') AND paymentsum = "ZCL_AMDP_SCALAR_FUNCTION_DEMO=>GET_MAX_PAYMENT_SUM" ( iv_mandt => SESSION_CONTEXT('CLIENT'), iv_carrid => :iv_carrid, iv_connid => :iv_connid ); ENDMETHOD. ENDCLASS. |
Обратите внимание на использование ключевого слова RETURN для передачи результата функции.
В примере мы вновь использовали ранее определённую скалярную функцию для формирования табличного результата новой табличной функции.
При вызове из ABAP на этапе компиляции не будет предупреждения, но в момент запуска возникнет дамп — CALL_METHOD_AMDP_FUNC_ILLEGAL:
1 2 3 4 5 6 |
PARAMETERS: p_carrid TYPE s_carr_id, p_connid TYPE s_conn_id. START-OF-SELECTION. DATA(lt_flights) = zcl_amdp_function_demo=>get_flight_with_max_sum( iv_carrid = p_carrid iv_connid = p_connid ). |
Табличная функция для ABAP CDS Table Functions
В ABAP CDS можно объявить так называемую табличную функцию, основное предназначение которой — предоставить некоторый набор данных сформированный внутри AMDP функции. Сделан такой функционал прежде всего для возможностей использования HANA Native функционала, который пока по той или иной причине не доступен в ABAP CDS.
Особенности:
- Функция может быть объявлена только как статический метод с публичной областью видимости. Не допускается объявление через интерфейсы.
- В определении метода должно использоваться ключевое дополнение FOR TABLE FUNCTION имяABAPCDSфункции. Соответственно одна и та же функция может быть использована только для одной ABAP CDS Table function.
- Параметры AMDP табличной функции не объявляются в описании метода, они должны быть описаны как параметры ABAP CDS. Параметры всегда имеют элементарный тип, не допускается опциональных параметров.
- Возвращаемый табличный тип определяется относительно структуры ABAP CDS, для зависимых от манданта CDS в структуре компонентов будет так же поле мандант. Тип таблицы — стандартная, ключ по умолчанию с именем result включает в себя все поля таблицы.
- Не могут быть напрямую вызваны из ABAP.
- Сначала создаётcя ABAP CDS с описанием входных параметров и структуры, а уже затем создаётся AMDP функция.
Созданный таким образом ABAP CDS мы можем использовать в других CDS или непосредственно для вызова из ABAP кода.
Рассмотрим пример ABAP CDS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@ClientHandling.type: #CLIENT_DEPENDENT define table function ZDEMO_CDS_GET_SCARR_SPFLI with parameters @Environment.systemField: #CLIENT clnt :abap.clnt, carrid :s_carr_id returns { client :s_mandt; carrname :s_carrname; connid :s_conn_id; cityfrom :s_from_cit; cityto :s_to_city; } implemented by method zcl_amdp_cds_function_demo=>get_scarr_spfli_for_cds; |
Код AMDP функции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
CLASS zcl_amdp_cds_function_demo DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb. CLASS-METHODS get_scarr_spfli_for_cds FOR TABLE FUNCTION zdemo_cds_get_scarr_spfli. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_amdp_cds_function_demo IMPLEMENTATION. METHOD get_scarr_spfli_for_cds BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING scarr spfli. RETURN SELECT sc.mandt as client, sc.carrname, sp.connid, sp.cityfrom, sp.cityto from scarr as sc inner join spfli as sp on sc.mandt = sp.mandt and sc.carrid = sp.carrid where sp.mandt = :clnt AND sp.carrid = :carrid ORDER BY sc.mandt, sc.carrname, sp.connid; endmethod. ENDCLASS. |
Вызов из ABAP кода:
1 2 3 4 5 6 7 |
PARAMETERS: p_carrid TYPE s_carr_id, p_connid TYPE s_conn_id. START-OF-SELECTION. SELECT * FROM zdemo_cds_get_scarr_spfli( carrid = @p_carrid ) WHERE connid = @p_connid INTO TABLE @DATA(lt_flights). |