AMDP (ABAP Managed Database Procedures) ermöglicht die Implementierung von SQLScript-Prozeduren direkt in ABAP-Klassen. Der Code wird auf der SAP HANA-Datenbank ausgeführt und bietet optimale Performance für datenintensive Operationen.
Voraussetzungen
- SAP HANA als Datenbank
- ABAP 7.40 SP05 oder höher
- Klasse muss Interface
IF_AMDP_MARKER_HDBimplementieren
Grundstruktur
CLASS zcl_amdp_example DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb.
TYPES: BEGIN OF ty_result, field1 TYPE string, field2 TYPE i, END OF ty_result, ty_results TYPE STANDARD TABLE OF ty_result WITH EMPTY KEY.
CLASS-METHODS: get_data IMPORTING VALUE(iv_param) TYPE string EXPORTING VALUE(et_result) TYPE ty_results.ENDCLASS.
CLASS zcl_amdp_example IMPLEMENTATION. METHOD get_data BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING ztable.
et_result = SELECT field1, field2 FROM ztable WHERE field1 = :iv_param; ENDMETHOD.ENDCLASS.Beispiele
1. Einfache AMDP-Prozedur
CLASS zcl_customer_amdp DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb.
TYPES: BEGIN OF ty_customer, kunnr TYPE kunnr, name1 TYPE name1_gp, ort01 TYPE ort01_gp, land1 TYPE land1_gp, END OF ty_customer, ty_customers TYPE STANDARD TABLE OF ty_customer WITH EMPTY KEY.
CLASS-METHODS: get_customers_by_country IMPORTING VALUE(iv_country) TYPE land1_gp EXPORTING VALUE(et_customers) TYPE ty_customers.ENDCLASS.
CLASS zcl_customer_amdp IMPLEMENTATION. METHOD get_customers_by_country BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING kna1.
et_customers = SELECT kunnr, name1, ort01, land1 FROM kna1 WHERE land1 = :iv_country; ENDMETHOD.ENDCLASS.
" AufrufDATA: lt_customers TYPE zcl_customer_amdp=>ty_customers.
zcl_customer_amdp=>get_customers_by_country( EXPORTING iv_country = 'DE' IMPORTING et_customers = lt_customers).
LOOP AT lt_customers INTO DATA(ls_cust). WRITE: / ls_cust-kunnr, ls_cust-name1, ls_cust-ort01.ENDLOOP.2. AMDP mit mehreren Tabellen
CLASS zcl_order_amdp DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb.
TYPES: BEGIN OF ty_order_detail, vbeln TYPE vbeln_va, posnr TYPE posnr_va, matnr TYPE matnr, kwmeng TYPE kwmeng, netwr TYPE netwr, kunnr TYPE kunnr, name1 TYPE name1_gp, END OF ty_order_detail, ty_order_details TYPE STANDARD TABLE OF ty_order_detail WITH EMPTY KEY.
CLASS-METHODS: get_order_details IMPORTING VALUE(iv_vbeln) TYPE vbeln_va EXPORTING VALUE(et_details) TYPE ty_order_details.ENDCLASS.
CLASS zcl_order_amdp IMPLEMENTATION. METHOD get_order_details BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING vbak vbap kna1.
et_details = SELECT p.vbeln, p.posnr, p.matnr, p.kwmeng, p.netwr, h.kunnr, c.name1 FROM vbap AS p INNER JOIN vbak AS h ON p.vbeln = h.vbeln INNER JOIN kna1 AS c ON h.kunnr = c.kunnr WHERE p.vbeln = :iv_vbeln; ENDMETHOD.ENDCLASS.3. AMDP mit Variablen und Logik
CLASS zcl_sales_amdp DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb.
TYPES: BEGIN OF ty_sales_summary, kunnr TYPE kunnr, name1 TYPE name1_gp, order_count TYPE i, total_value TYPE netwr, END OF ty_sales_summary, ty_sales_summaries TYPE STANDARD TABLE OF ty_sales_summary WITH EMPTY KEY.
CLASS-METHODS: get_sales_summary IMPORTING VALUE(iv_year) TYPE gjahr EXPORTING VALUE(et_summary) TYPE ty_sales_summaries.ENDCLASS.
CLASS zcl_sales_amdp IMPLEMENTATION. METHOD get_sales_summary BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING vbak kna1.
-- Lokale Variable für Datumsbereich DECLARE lv_from_date DATE; DECLARE lv_to_date DATE;
lv_from_date = CONCAT(:iv_year, '0101'); lv_to_date = CONCAT(:iv_year, '1231');
-- Aggregierte Abfrage et_summary = SELECT k.kunnr, k.name1, COUNT(*) AS order_count, SUM(v.netwr) AS total_value FROM vbak AS v INNER JOIN kna1 AS k ON v.kunnr = k.kunnr WHERE v.erdat BETWEEN :lv_from_date AND :lv_to_date GROUP BY k.kunnr, k.name1 ORDER BY total_value DESC; ENDMETHOD.ENDCLASS.4. AMDP mit IF/CASE-Logik
METHOD calculate_discount BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING zcustomers.
et_result = SELECT kunnr, name1, total_sales, CASE WHEN total_sales >= 100000 THEN 15 WHEN total_sales >= 50000 THEN 10 WHEN total_sales >= 10000 THEN 5 ELSE 0 END AS discount_percent FROM zcustomers;ENDMETHOD.5. AMDP mit Schleifen
METHOD process_data BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING ztable.
DECLARE lv_counter INTEGER; DECLARE lv_max INTEGER;
-- Daten laden lt_data = SELECT * FROM ztable;
-- Zähler initialisieren lv_counter = 1; SELECT COUNT(*) INTO lv_max FROM :lt_data;
-- Schleife WHILE lv_counter <= lv_max DO -- Verarbeitung lv_counter = lv_counter + 1; END WHILE;
et_result = SELECT * FROM :lt_data;ENDMETHOD.6. AMDP mit temporären Tabellen
METHOD complex_calculation BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING vbak vbap.
-- Erste temporäre Tabelle lt_headers = SELECT vbeln, kunnr, erdat, netwr FROM vbak WHERE erdat >= ADD_DAYS(CURRENT_DATE, -365);
-- Zweite temporäre Tabelle basierend auf erster lt_items = SELECT p.* FROM vbap AS p INNER JOIN :lt_headers AS h ON p.vbeln = h.vbeln;
-- Aggregation lt_summary = SELECT h.kunnr, COUNT(DISTINCT h.vbeln) AS order_count, SUM(i.netwr) AS item_total FROM :lt_headers AS h INNER JOIN :lt_items AS i ON h.vbeln = i.vbeln GROUP BY h.kunnr;
-- Ergebnis et_result = SELECT * FROM :lt_summary;ENDMETHOD.7. CDS Table Function
" CDS View Definition@EndUserText.label: 'Sales by Customer (Table Function)'define table function ZTF_SALES_BY_CUSTOMER with parameters @Environment.systemField: #SYSTEM_DATE p_date : abap.dats returns { key kunnr : abap.char(10); name1 : abap.char(35); total : abap.dec(15,2); } implemented by method zcl_tf_sales=>get_sales;
" ABAP ImplementierungCLASS zcl_tf_sales DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb.
CLASS-METHODS: get_sales FOR TABLE FUNCTION ztf_sales_by_customer.ENDCLASS.
CLASS zcl_tf_sales IMPLEMENTATION. METHOD get_sales BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING vbak kna1.
RETURN SELECT k.kunnr, k.name1, SUM(v.netwr) AS total FROM vbak AS v INNER JOIN kna1 AS k ON v.kunnr = k.kunnr WHERE v.erdat <= :p_date GROUP BY k.kunnr, k.name1; ENDMETHOD.ENDCLASS.
" Verwendung in ABAPSELECT * FROM ztf_sales_by_customer( p_date = @sy-datum ) INTO TABLE @DATA(lt_sales).8. AMDP mit Fehlerbehandlung
METHOD process_with_error BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING ztable.
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- Fehlerbehandlung et_errors = SELECT ::SQL_ERROR_CODE AS error_code, ::SQL_ERROR_MESSAGE AS error_message FROM DUMMY; END;
-- Normale Verarbeitung et_result = SELECT * FROM ztable;ENDMETHOD.9. AMDP mit USING anderer AMDP
CLASS zcl_amdp_chain DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb.
CLASS-METHODS: helper_method IMPORTING VALUE(iv_input) TYPE string EXPORTING VALUE(et_result) TYPE ty_results.
CLASS-METHODS: main_method EXPORTING VALUE(et_final) TYPE ty_finals.ENDCLASS.
CLASS zcl_amdp_chain IMPLEMENTATION. METHOD helper_method BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING ztable.
et_result = SELECT * FROM ztable WHERE field = :iv_input; ENDMETHOD.
METHOD main_method BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING zcl_amdp_chain=>helper_method.
-- Andere AMDP aufrufen CALL "ZCL_AMDP_CHAIN=>HELPER_METHOD"( iv_input => 'VALUE', et_result => lt_temp );
et_final = SELECT * FROM :lt_temp; ENDMETHOD.ENDCLASS.10. Performance: AMDP vs. Open SQL
" === Open SQL (Standard) ===" Daten werden vom DB-Server zum App-Server übertragenSELECT * FROM vbak INTO TABLE @DATA(lt_orders).
LOOP AT lt_orders INTO DATA(ls_order). " Verarbeitung auf App-Server IF ls_order-netwr > 10000. " ... ENDIF.ENDLOOP.
" === AMDP (optimiert) ===" Verarbeitung direkt auf der Datenbankzcl_order_amdp=>get_high_value_orders( EXPORTING iv_min_value = 10000 IMPORTING et_orders = lt_high_value_orders)." Nur relevante Daten werden übertragen11. AMDP mit Window Functions
METHOD get_ranked_sales BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING vbak.
et_result = SELECT kunnr, vbeln, netwr, ROW_NUMBER() OVER ( PARTITION BY kunnr ORDER BY netwr DESC ) AS rank_per_customer, SUM(netwr) OVER ( PARTITION BY kunnr ) AS total_per_customer FROM vbak;ENDMETHOD.12. Praktisches Beispiel: Hierarchie-Auflösung
METHOD resolve_hierarchy BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING zorg_units.
-- Rekursive Hierarchie-Auflösung mit HANA et_hierarchy = SELECT node_id, parent_id, name, HIERARCHY_LEVEL AS level FROM HIERARCHY ( SOURCE ( SELECT * FROM zorg_units ) START WHERE parent_id IS NULL NO ORPHANS );ENDMETHOD.SQLScript-Grundlagen
-- VariablenDECLARE lv_var INTEGER;DECLARE lv_text NVARCHAR(100);
-- Zuweisunglv_var = 42;lv_text = 'Hello';
-- Tabellenvariablelt_data = SELECT * FROM table;
-- IF-BedingungIF :lv_var > 10 THEN -- ...ELSEIF :lv_var > 5 THEN -- ...ELSE -- ...END IF;
-- WHILE-SchleifeWHILE :lv_counter < 100 DO lv_counter = lv_counter + 1;END WHILE;
-- FOR-SchleifeFOR i IN 1..10 DO -- ...END FOR;
-- CursorFOR row AS cursor_name DO -- row.fieldEND FOR;Wichtige Hinweise / Best Practice
- AMDP nur für SAP HANA – nicht portabel zu anderen Datenbanken.
- READ-ONLY für lesende Operationen (Default, empfohlen).
- USING deklariert alle verwendeten Datenbankobjekte und AMDPs.
- Verwenden Sie Table Functions für Verwendung in CDS Views.
- Große Datenmengen auf DB verarbeiten statt übertragen.
- IF_AMDP_MARKER_HDB muss implementiert werden.
- Testen Sie in HANA Studio oder SQL Console.
- Debugging über HANA-Debugger möglich (ab 7.50).
- Vermeiden Sie zu viele Schleifen – mengenbasiert denken.
- Kombinieren Sie mit CDS Views für optimales Datenmodell.