2016-06-09 3 views
6

Предположим, у меня есть таблица базы данных, представляющей собой иерархическую структуру, со следующими столбцами:Как получить все дочерние узлы иерархической структуры в ABAP?

  • идентификатор
  • predecessor_id
  • имя

Начиная с данного ID, я должен быть в состоянии для извлечения всех дочерних узлов (а не только для прямых детей). Так как общие выражения таблицы (WITH RECURSIVE) недоступны в ABAP, какой был бы лучший способ решить эту проблему?

Возможное решение, о котором я думал, это итерация через результирующий набор (LOOP или с помощью курсора) и рекурсивно вызывать функцию, которая извлекает прямые дочерние узлы. Однако я надеюсь, что есть более элегантный подход.

+0

Я не вижу другого способа узнать всех потомков, а не рекурсивно выбирать детей - именно то, о чем вы думали. Там, где это была проблема с производительностью, в некоторых случаях мы ввели столбец «master_id», содержащий идентификатор верхнего уровня этого элемента, и вторичный индекс для базы данных для него, – rplantiko

+0

Я не думаю, что это слишком широкое, особенно учитывая, что комментарий @ rplantiko - это почти полный ответ. –

ответ

4

Прежде всего вам нужно знать, что SAP не является базой данных, а OpenSQL всегда переводится на SQL-диалект базовой базы данных. Если базовая база данных не поддерживает WITH или WITH RECURSIVE, и из того, что я вижу из следующих article, не каждая база данных делает это, а добавление ее в OpenSQL не имеет никакого смысла, поскольку во многих случаях не было бы ничего, чтобы отобразить ее на ,

Итак, первое решение будет таким, как вы предложили, написав отдельную рекурсивную функцию/метод/подпрограмму или если вы действительно хотите использовать базовые функции базы данных, вы можете использовать интерфейс ADBC. Если вы знакомы с JDBC, тогда концепция не должна быть новой для вас. Если вы делаете это для продуктивных целей, однако вы должны убедиться, что в будущем существует вероятность того, что в будущем произойдет миграция базы данных.

Решение с ADBC, которое работает для меня в системе SAP с базовой базой данных Oracle.

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

Я не сказал, что «SAP - это база данных». Кроме того, у меня уже есть решение с использованием рекурсивного подхода. Вопрос в том, можно ли это решить другим способом. –

+0

@TudorCiotlos Из-за явного любопытства ... Какая СУБД - ваша система SAP? – Jagger

+0

@Jagger СУБД в системе SAP, в которой я сейчас работаю, - это Oracle 11.2. –