Zunächst müssen Sie wissen, dass SAP keine Datenbank ist und OpenSQL immer in den SQL-Dialekt der zugrunde liegenden Datenbank übersetzt wird. Wenn die zugrunde liegende Datenbank WITH
oder WITH RECURSIVE
nicht unterstützt und aus dem, was ich aus den folgenden article ersehen kann, nicht jede Datenbank tut, würde das Hinzufügen zu OpenSQL keinen Sinn ergeben, da es in vielen Fällen nichts geben würde .
Also wäre die erste Lösung wie Sie vorgeschlagen haben, eine separate rekursive Funktion/Methode/Subroutine schreiben oder wenn Sie wirklich zugrundeliegende Datenbankfunktionalität verwenden möchten, können Sie ADBC
Schnittstelle verwenden. Wenn Sie mit JDBC
vertraut sind, sollte das Konzept für Sie nicht neu sein. Wenn Sie dies für produktive Zwecke tun, sollten Sie jedoch sicherstellen, dass es in Zukunft eine geringe oder keine Wahrscheinlichkeit für eine Datenbankmigration gibt.
Die Lösung mit ADBC
, die für mich auf einem SAP-System mit einer zugrunde liegenden Oracle-Datenbank funktioniert.
REPORT Z_ADBC_TEST.
CLASS lcl_test DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
main.
ENDCLASS.
CLASS lcl_test IMPLEMENTATION.
METHOD main.
DATA lo_sql_connection TYPE REF TO cl_sql_connection.
DATA lo_sql_statement TYPE REF TO cl_sql_statement.
DATA lo_sql_result_set TYPE REF TO cl_sql_result_set.
TYPES BEGIN OF lt_result_struct,
n TYPE i,
fact TYPE i,
END OF lt_result_struct.
DATA lt_result TYPE TABLE OF t_result_struct WITH DEFAULT KEY.
DATA lr_ref_to_data TYPE REF TO data.
FIELD-SYMBOLS <fs_result> LIKE LINE OF lt_result.
lo_sql_connection = cl_sql_connection=>get_connection().
lo_sql_statement = lo_sql_connection->create_statement().
GET REFERENCE OF lt_result INTO lr_ref_to_data.
lo_sql_result_set = lo_sql_statement->execute_query(
`WITH temp(n, fact) ` &&
`AS (SELECT 0,1 FROM dual UNION ALL ` &&
`SELECT n+1,(n+1)*fact FROM temp ` &&
`WHERE n < 9) ` &&
`SELECT * FROM temp`
).
lo_sql_result_set->set_param_table(lr_ref_to_data).
WHILE lo_sql_result_set->next_package() > 0.
LOOP AT lt_result ASSIGNING <fs_result>.
WRITE:/<fs_result>-n, <fs_result>-fact.
ENDLOOP.
ENDWHILE.
ENDMETHOD.
ENDCLASS.
END-OF-SELECTION.
lcl_test=>main().
Ich sehe keine andere Möglichkeit, alle Nachkommen herauszufinden, als rekursiv Kinder auszuwählen - genau das, woran Sie gedacht haben. Wo dies ein Performance-Problem war, haben wir in einigen Fällen eine Spalte 'master_id' eingeführt, die die ID der obersten Ebene des Elements enthält, und einen sekundären Index für die Datenbank, – rplantiko
. Ich denke nicht, dass dies besonders zu weit gefasst ist da @ rplantikos Kommentar fast eine vollständige Antwort ist. –