2016-06-09 13 views
6

Supponiamo che io ho una tabella del database che rappresenta una struttura gerarchica, con le seguenti colonne:Come posso recuperare tutti i nodi figlio di una struttura gerarchica in ABAP?

  • id
  • predecessor_id
  • nome

Partendo da un dato ID, devo essere in grado per recuperare tutti i nodi figlio (non solo i bambini diretti). Poiché le espressioni di tabella comuni (WITH RECURSIVE) non sono disponibili in ABAP, quale sarebbe il modo migliore per risolvere questo problema?

Una possibile soluzione a cui ho pensato sta iterando attraverso un set di risultati (LOOP o utilizzando un cursore) e chiama ricorsivamente una funzione che recupera i nodi figlio diretti. Tuttavia, spero che ci sia un approccio più elegante.

+0

Non vedo nessun altro modo di scoprire tutti i discendenti che selezionando ricorsivamente i bambini - esattamente quello a cui hai pensato. Laddove questo era un problema di prestazioni, in alcuni casi abbiamo introdotto una colonna 'master_id', contenente l'id di livello superiore dell'elemento e un indice secondario sul database per esso, – rplantiko

+0

Non penso che sia troppo ampio, specialmente dato che il commento di @ rplantiko è quasi una risposta completa. –

risposta

4

Prima di tutto è necessario sapere che SAP non è un database e OpenSQL è sempre tradotto nel dialetto SQL del database sottostante. Se il database sottostante non supporta WITH o WITH RECURSIVE e da quello che vedo dal seguente article non tutti i database lo fanno, quindi aggiungerlo a OpenSQL non avrebbe senso in molti casi non ci sarebbe nulla da mappare a .

Quindi la prima soluzione sarebbe come proposto, scrivendo una funzione/metodo/subroutine ricorsiva separata o se si desidera veramente utilizzare la funzionalità di database sottostante è possibile utilizzare l'interfaccia ADBC. Se hai familiarità con JDBC allora il concetto non dovrebbe essere nuovo per te. Se lo fai per scopi produttivi, dovresti assicurarti che ci sia una probabilità minima o nulla di una migrazione del database in futuro.

La soluzione con ADBC che funziona per me su un sistema SAP con un database Oracle sottostante.

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

Non ho affermato che "SAP è un database". Inoltre, ho già la soluzione utilizzando l'approccio ricorsivo implementato. La domanda era se questo potesse essere risolto in un modo diverso. –

+0

@TudorCiotlos Per pura curiosità ... Su quale RDBMS è basato il tuo sistema SAP? – Jagger

+0

@Jagger L'RDBMS sul sistema SAP attualmente in uso è Oracle 11.2. –

Problemi correlati