Deep Copy hierarchies in v4

Customer wants to copy a hierarchy and therefore needs a "deep copy" functionality.

Examples of customer request: "can you copy a entity with its children? Replicate a hierachy?" and SUPPORT-4410 (related: MDM-6369)

This can be achieved using PL/SQL. 


deep copy PL/SQL sample
create or replace procedure perform_deep_copy(p_loadid number)
as
    v_root number;
    v_copied_from_root number;
    v_hierarchy_type varchar2(40);
    v_credate timestamp(3);
    v_creator varchar2(128);
begin
    /* re-adjust the parent root node */
    update SA_NODE
    set F_ROOT_NODE = ID
    where B_LOADID = p_loadid
    and IS_ROOT = '1'
    ;
    /* 
     1. get the root node being copied in the current load
    */
    select
        ID, B_COPIEDFROM, HIERARCHY_TYPE, B_CREDATE, B_CREATOR
    into    v_root, v_copied_from_root, v_hierarchy_type, v_credate, v_creator
    from SA_NODE
    where B_LOADID = p_loadid
    and IS_ROOT = '1'
    ;

    /*
    2. copy all child nodes from the copied_from_root nodes
    */
    insert into SA_NODE (
            B_LOADID,    B_CLASSNAME,    B_CREDATE,    B_CREATOR,
            ID,    HIERARCHY_TYPE,    NAME,    DESCRIPTION,    IS_ROOT,
            F_ROOT_NODE,  F_PARENT, B_COPIEDFROM,
            F_CUSTOMER,   F_FACILITY,   F_OMU)
    select
        p_loadid, 'Node', v_credate, v_creator,
        SEQ_NODE.NEXTVAL, v_hierarchy_type, NAME, DESCRIPTION, IS_ROOT,
        v_root, F_PARENT, ID,
        F_CUSTOMER, F_FACILITY, F_OMU
    from
        GD_NODE
    where 
        nvl(IS_ROOT, '0') = '0'
    and F_ROOT_NODE = v_copied_from_root
    ;

    /*
    3. change the parent to reflect the new parent
    */

    merge into SA_NODE T
    using (
        select C.ID, P.ID F_NEW_PARENT
        from SA_NODE C
            inner join SA_NODE P on (C.F_PARENT = P.B_COPIEDFROM)
        where 
            C.B_LOADID = p_loadid
        and P.B_LOADID = p_loadid
        and nvl(C.IS_ROOT, '0') = '0'
        ) S
    on (S.ID = T.ID)
    when matched then
        update set T.F_PARENT = S.F_NEW_PARENT
    ;
end;