6

假设我有一个表示分层结构的数据库表,其中包含以下列:

  • ID
  • 前任_id
  • 姓名

从给定的 ID 开始,我必须能够检索所有子节点(不仅是直接子节点)。由于 ABAP 中不提供公用表表达式(带递归),因此解决此问题的最佳方法是什么?

我想到的一个可能的解决方案是遍历结果集(循环或使用游标),并递归调用检索直接子节点的函数。但是,我希望有一种更优雅的方法。

4

1 回答 1

4

首先你需要知道 SAP 不是数据库,OpenSQL 总是被翻译成底层数据库的 SQL 方言。如果底层数据库不支持WITH,或者WITH RECURSIVE从我从下一篇文章中看到的并不是每个数据库都支持,那么将它添加到 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( ).
于 2016-06-13T15:15:22.177 回答