Рассмотрим пример, в котором присутствует иерархия.
В системе есть классификация, т.е. могут быть вышестоящие и подчиненные классы.
Возьмем класс 3011803, обозначенный как Джем абрикосовый.
Иерархический список выглядит следующим образом:
Наша задача – реализовать модель данных, которая умеет возвращать список вышестоящий классов.
Первый способ – реализовать всю модель на уровне CDS
Создадим CDS нижнего уровня.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@AbapCatalog.sqlViewName: 'ZIHIERDEMO' @AbapCatalog.compiler.compareFilter: true @AbapCatalog.preserveKey: true @AccessControl.authorizationCheck: #CHECK @EndUserText.label: 'Demo Hierarhy' define view ZI_HIER_DEMO as select from kssk association [0..1] to swor as _swor on _swor.clint = $projection.clint association [1..1] to ZI_HIER_DEMO as _tree on _tree.clint = $projection.objek { _tree, clint, objek, _swor.kschl } group by objek, clint, _swor.kschl |
Логика простая, родитель – текущая запись, дочерний элемент – данные из ассоциации _tree, которую мы пробрасываем целиком.
Теперь организуем иерархическую CDS, с параметром, от которого будет начинаться “развертка” иерархии.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
define hierarchy ZI_HIER_DEMO_TREE with parameters p_id : cuobn as parent child hierarchy( source ZI_HIER_DEMO child to parent association _tree start where objek = :p_id siblings order by objek ascending ) { objek, clint, kschl } |
В нашем случае мы должны указать в качестве параметра внутренний номер класса для абрикосового джема
Пробуем вызвать CDS, используя ABAP SQL
1 2 3 4 5 6 |
CONSTANTS: lc_objek TYPE kssk-objek VALUE '0000000177'. SELECT * FROM zi_hier_demo_tree( p_id = @lc_objek ) INTO TABLE @DATA(lt_cds_hier). |
Второй способ решения – использовать define hierarchy на уровне ABAP SQL.
В этом случае мы не создаем ZI_HIER_DEMO_TREE, а выносим эту часть на уровень ABAP SQL, используя в качестве источника CDS zi_hier_demo.
1 2 3 4 5 6 |
SELECT FROM HIERARCHY( SOURCE zi_hier_demo CHILD TO PARENT ASSOCIATION _tree START WHERE objek = @lc_objek SIBLINGS ORDER BY objek ASCENDING ) FIELDS * INTO TABLE @DATA(lt_abap_hier). |
Третий способ решения – без использования CDS.
Всю часть можно реализовать на ABAP. Будем использовать CTE (обобщенные табличные выражения)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
WITH +cte_tree_source as ( SELECT FROM kssk FIELDS clint, objek ) WITH ASSOCIATIONS ( JOIN TO MANY +cte_tree_source as _tree ON _tree~clint = +cte_tree_source~objek, JOIN TO ONE swor as _swor ON _swor~clint = +cte_tree_source~clint ) SELECT FROM HIERARCHY( SOURCE +cte_tree_source CHILD TO PARENT ASSOCIATION _tree START WHERE objek = @lc_objek SIBLINGS ORDER BY objek ASCENDING ) FIELDS clint, objek, \_swor[ (1) LEFT OUTER ]-kschl INTO TABLE @DATA(lt_abap_hier_with_cte). |
Процесс схож с первым способом.
Вместо ZI_HIER_DEMO мы организуем +cte_tree_source как основной ресурс, и предоставляем ассоциацию _tree для развертки иерархии. В теле основного запроса обращаемся к HIERARCHY, указывая источник и остальные параметры.
Дополнительно выбираем название класса из таблицы swor через ассоциацию.
Спасибо всем, кто прочитал до конца. Надеюсь, эта небольшая статья будет кому-то полезна 🙂