2016-06-09 8 views
6

Angenommen, ich eine Datenbanktabelle haben eine hierarchische Struktur, mit den folgenden Spalten darstellt:Wie kann ich alle untergeordneten Knoten einer hierarchischen Struktur in ABAP abrufen?

  • id
  • Name

Ausgehend von einer bestimmten ID predecessor_id, ich in der Lage sein, um alle Kindknoten (nicht nur die direkten Kinder) abzurufen. Da allgemeine Tabellenausdrücke (mit RECURSIVE) in ABAP nicht verfügbar sind, was wäre der beste Weg, dies zu lösen?

Eine mögliche Lösung, an die ich gedacht habe, besteht darin, eine Ergebnismenge zu durchlaufen (LOOP oder mit einem Cursor) und rekursiv eine Funktion aufzurufen, die die direkten Kindknoten abruft. Ich hoffe jedoch, dass es einen eleganteren Ansatz gibt.

+0

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

+0

. Ich denke nicht, dass dies besonders zu weit gefasst ist da @ rplantikos Kommentar fast eine vollständige Antwort ist. –

Antwort

4

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(). 
+0

Ich habe nicht gesagt, dass "SAP eine Datenbank ist". Auch habe ich bereits die Lösung mit dem rekursiven Ansatz implementiert. Die Frage war, ob dies auf andere Weise gelöst werden könnte. –

+0

@TudorCiotlos Aus purer Neugier ... Auf welchem ​​RDBMS basiert Ihr SAP-System? – Jagger

+0

@Jagger Das RDBMS auf dem SAP-System, an dem ich gerade arbeite, ist Oracle 11.2. –