假設我有代表高等教育層次結構的數據庫表,有以下欄目:如何在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的評論幾乎是一個完整的答案。 –