假设我有代表高等教育层次结构的数据库表,有以下栏目:如何在ABAP中检索层次结构的所有子节点?
- ID
- predecessor_id
- 名
从给定的ID开始,我必须能够检索所有的孩子节点(不仅是直接的孩子)。由于公用表表达式(WITH RECURSIVE)在ABAP中不可用,因此解决此问题的最佳方法是什么?
我想到的一种可能的解决方案是遍历结果集(LOOP或通过使用游标),并递归地调用一个函数来检索直接的子节点。不过,我希望有一个更优雅的方法。
假设我有代表高等教育层次结构的数据库表,有以下栏目:如何在ABAP中检索层次结构的所有子节点?
从给定的ID开始,我必须能够检索所有的孩子节点(不仅是直接的孩子)。由于公用表表达式(WITH RECURSIVE)在ABAP中不可用,因此解决此问题的最佳方法是什么?
我想到的一种可能的解决方案是遍历结果集(LOOP或通过使用游标),并递归地调用一个函数来检索直接的子节点。不过,我希望有一个更优雅的方法。
首先您需要知道SAP不是数据库,并且OpenSQL总是被转换为底层数据库的SQL方言。如果底层数据库不支持WITH
或WITH RECURSIVE
,并且从我看到的以下article不是每个数据库都这样做,那么将它添加到OpenSQL将没有任何意义,因为在许多情况下,不会有任何东西将其映射到。因此,第一种解决方案将按照您的建议编写一个单独的递归函数/方法/子例程,或者如果您确实想要使用底层数据库功能,则可以使用接口ADBC
。如果你熟悉JDBC
那么这个概念对你来说应该不是新鲜事。如果您为了生产目的而这样做,但是您应该确保未来数据库迁移的可能性很小或根本不可能。
ADBC
的解决方案适用于具有基础Oracle数据库的SAP系统。
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().
我没有说“SAP是一个数据库”。另外,我已经使用递归方法实施了解决方案。问题是如果这可以以不同的方式解决。 –
@TudorCiotlos出于纯粹的好奇心......您的SAP系统建立在哪个RDBMS上? – Jagger
@Jagger我目前使用的SAP系统上的RDBMS是Oracle 11.2。 –
我没有办法找到所有的后代,而不是通过递归选择孩子 - 正是你所想的。如果这是一个性能问题,在某些情况下,我们引入了一个名为master_id的列,其中包含元素的顶级ID以及数据库上的二级索引 – rplantiko
我不认为这太宽泛,特别是因为@ rplantiko的评论几乎是一个完整的答案。 –