Прежде всего вам нужно знать, что 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().
Я не вижу другого способа узнать всех потомков, а не рекурсивно выбирать детей - именно то, о чем вы думали. Там, где это была проблема с производительностью, в некоторых случаях мы ввели столбец «master_id», содержащий идентификатор верхнего уровня этого элемента, и вторичный индекс для базы данных для него, – rplantiko
Я не думаю, что это слишком широкое, особенно учитывая, что комментарий @ rplantiko - это почти полный ответ. –