create or replace package UDO_PKG_EQUIPTCF as /* Формирование дерева состава оборудования */ procedure EQCONFIG_HIER ( NPEQCONFIG in number, -- Рег. номер родительского узла состава оборудования COUT out clob -- Сериализованное XML-представление дерева ); /* Формирование списка технических объектов для выбранного узла состава оборудования */ procedure EQCONFIG_THOBJ_DG ( NPEQCONFIG in number -- Рег. номер родительского узла состава оборудования ); end UDO_PKG_EQUIPTCF; / create or replace package body UDO_PKG_EQUIPTCF as /* Формирование ветки дерева состава оборудования */ function EQCONFIG_HIER_NODE ( NCUR in integer, -- Курсор документа для результата NCOMPANY in number, -- Рег. номер организации NPEQCONFIG in number -- Рег. номер родительского узла состава оборудования ) return PKG_XMAKE.TNODE -- XML-описание веток дерева is XLEAF PKG_XMAKE.TNODE; -- Текущий лист XCHILD PKG_XMAKE.TNODE; -- Дочерние листы текущего XRES PKG_XMAKE.TNODE; -- Буфер для результата begin /* Обходим состав оборудования с заданного корня */ for C in (select M.RN NRN, M.EQPARENT NHRN, DECODE(M.FICT_REC, 0, M.NAME, DECODE(OL.RN, null, M.NAME, OL.NAME)) SNAME, case when exists (select null from EQCONFIG C where C.EQPARENT = M.RN and exists (select null from V_USERPRIV_HIER_SINGL UP where UP.HIERARCHY = C.RN)) then 1 else 0 end NHASCHILDREN from EQCONFIG M, EQOBJLEVEL OL where M.PR_OBJ_LEVEL = OL.RN(+) and ((M.FICT_REC = 0) or ((M.FICT_REC = 1) and (CMP_VC2(M.NAME, F_EQCONFIG_EXTRANAME(0)) = 1))) and exists (select null from V_USERPRIV_HIER_SINGL UP where UP.HIERARCHY = M.RN) and COALESCE(M.EQPARENT, 0) = NPEQCONFIG and M.COMPANY = NCOMPANY) loop /* Если есть дочерние ветки */ if (C.NHASCHILDREN = 1) then /* Добавим фиктивную дочернюю запись для индикации наличия дочерних на клиенте */ XCHILD := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'children', RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR, RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR, SNAME => 'id', SVALUE => C.NRN || '_loader'), RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR, SNAME => 'label', SVALUE => 'Минуточку...'))); else XCHILD := null; end if; /* Соберём лист */ XLEAF := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'children', RATTRIBUTES => PKG_XMAKE.ATTRIBUTES(ICURSOR => NCUR, RATTRIBUTE00 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR, SNAME => 'id', SVALUE => C.NRN), RATTRIBUTE01 => PKG_XMAKE.ATTRIBUTE(ICURSOR => NCUR, SNAME => 'label', SVALUE => C.SNAME)), RNODE00 => XCHILD); /* Соберём листы в ветку */ XRES := PKG_XMAKE.CONCAT(ICURSOR => NCUR, RNODE00 => XRES, RNODE01 => XLEAF); end loop; /* Вернём собранное */ return XRES; end EQCONFIG_HIER_NODE; /* Формирование дерева состава оборудования */ procedure EQCONFIG_HIER ( NPEQCONFIG in number, -- Рег. номер родительского узла состава оборудования COUT out clob -- Сериализованное XML-представление дерева ) is NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации NCUR integer; -- Курсор документа для результата XDOC PKG_XMAKE.TNODE; -- Документ для результата begin /* Открываем документ */ NCUR := PKG_XMAKE.OPEN_CURSOR(); /* Формируем XML-представление ветки для запрошенного родителя */ XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => EQCONFIG_HIER_NODE(NCUR => NCUR, NCOMPANY => NCOMPANY, NPEQCONFIG => NPEQCONFIG)); /* Конвертируем в CLOB */ COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR, ITYPE => PKG_XMAKE.CONTENT_, RNODE => XDOC, RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_, SENCODING => PKG_XHEADER.ENCODING_UTF_, SSTANDALONE => PKG_XHEADER.STANDALONE_YES_)); /* Закрываем документ */ PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR); end EQCONFIG_HIER; /* Формирование списка технических объектов для выбранного узла состава оборудования */ procedure EQCONFIG_THOBJ_DG ( NPEQCONFIG in number -- Рег. номер родительского узла состава оборудования ) is begin null; end EQCONFIG_THOBJ_DG; end UDO_PKG_EQUIPTCF; /