create or replace package PKG_P8PANELS_QE as

  /* Получение списка доступных сущностей */
  procedure ENTITY_LIST
  (
    SSEARCH                 in varchar2, -- Поисковый запрос
    COUT                    out clob     -- Сериализованный список доступных сущностей
  );
  
  /* Получение данных о запросе */
  procedure QUERY
  (
    NRN                     in number,  -- Рег. номер запроса
    COUT                    out clob    -- Сериализованное описание запроса
  );

  /* Получение списка запросов */
  procedure QUERY_LIST
  (
    COUT                    out clob    -- Сериализованный список запросов
  );
  
  /* Добавление запроса */
  procedure QUERY_INSERT
  (
    SCODE                   in varchar2, -- Мнемокод
    SNAME                   in varchar2, -- Наименование
    NRN                     out number   -- Рег. номер добавленного запроса
  );
  
  /* Исправление запроса */
  procedure QUERY_UPDATE
  (
    NRN                     in number,   -- Рег. номер запроса
    SCODE                   in varchar2, -- Мнемокод
    SNAME                   in varchar2  -- Наименование
  );

  /* Удаление запроса */
  procedure QUERY_DELETE
  (
    NRN                     in number   -- Рег. номер запроса
  );
  
  /* Установка признака "готовности" запроса */
  procedure QUERY_READY_SET
  (
    NRN                     in number,  -- Рег. номер запроса
    NREADY                  in number   -- Флаг готовности к использованию (0 - нет, 1 - да)
  );
  
  /* Установка признака "публичности" запроса */
  procedure QUERY_PBL_SET
  (
    NRN                     in number,  -- Рег. номер запроса
    NPBL                    in number   -- Флаг публичности (0 - приватный, 1 - публичный)
  );
  
  /* Добавление сущности в запрос */
  procedure QUERY_ENT_ADD
  (
    NRN                     in number,   -- Рег. номер запроса
    SNAME                   in varchar2, -- Имя
    STYPE                   in varchar2  -- Тип (см. константы SENT_TYPE_*)
  );
  
  /* Удаление сущности из запроса */
  procedure QUERY_ENT_REMOVE
  (
    NRN                     in number,   -- Рег. номер запроса
    SID                     in varchar2  -- Идентификатор сущности
  );

  /* Установка координат сущности в редакторе диаграммы запроса */
  procedure QUERY_ENT_POSITION_SET
  (
    NRN                     in number,   -- Рег. номер запроса
    SID                     in varchar2, -- Идентификатор сущности
    NX                      in number,   -- Координата по оси абсцисс
    NY                      in number    -- Координата по оси ординат
  );
  
  /* Получение состава атрибутов сущности */
  procedure QUERY_ENT_ATTRS_GET
  (
    NRN                     in number,   -- Рег. номер запроса
    SID                     in varchar2, -- Идентификатор сущности
    COUT                    out clob     -- Сериализованное описание атрибутов сущности
  );

  /* Установка состава атрибутов сущности */
  procedure QUERY_ENT_ATTRS_SET
  (
    NRN                     in number,   -- Рег. номер запроса
    SID                     in varchar2, -- Идентификатор сущности
    CATTRS                  in clob      -- Сериализованное описание атрибутов сущности  (BASE64 XML)
  );
  
  /* Добавление связи в запрос */
  procedure QUERY_RL_ADD
  (
    NRN                     in number,   -- Рег. номер запроса
    SSOURCE                 in varchar2, -- Идентификатор атрибута-источника
    STARGET                 in varchar2  -- Идентификатор атрибута-приёмника
  );

  /* Удаление связи из запроса */
  procedure QUERY_RL_REMOVE
  (
    NRN                     in number,  -- Рег. номер запроса
    SID                     in varchar2 -- Идентификатор связи
  );
  
  /* Установка признака обязательности связи */
  procedure QUERY_RL_MANDATORY_SET
  (
    NRN                     in number,   -- Рег. номер запроса
    SID                     in varchar2, -- Идентификатор связи
    NMANDATORY              in number    -- Флаг обязательности (1 - да, 0 - нет)
  );
  
  /* Добавление аргумента запроса */
  procedure QUERY_OPT_ARG_ADD
  (
    NRN                     in number,   -- Рег. номер запроса
    SNAME                   in varchar2, -- Имя
    STITLE                  in varchar2, -- Заголовок
    NDATA_TYPE              in number,   -- Тип данных (см. константы PKG_STD.DATA_TYPE_*)
    NMANDATORY              in number,   -- Флаг обязательности (1 - да, 0 - нет)
    SVALUE                  in varchar2  -- Значение для отладки (строковое представление для всех типов данных)
  );

  /* Изменение аргумента запроса */
  procedure QUERY_OPT_ARG_EDIT
  (
    NRN                     in number,   -- Рег. номер запроса
    SNAME                   in varchar2, -- Имя
    STITLE                  in varchar2, -- Заголовок
    NDATA_TYPE              in number,   -- Тип данных (см. константы PKG_STD.DATA_TYPE_*)
    NMANDATORY              in number,   -- Флаг обязательности (1 - да, 0 - нет)
    SVALUE                  in varchar2  -- Значение для отладки (строковое представление для всех типов данных)
  );

  /* Удаление аргумента запроса */
  procedure QUERY_OPT_ARG_REMOVE
  (
    NRN                     in number,  -- Рег. номер запроса
    SNAME                   in varchar2 -- Имя
  );
  
  /* Установка условий отбора запроса */
  procedure QUERY_OPT_COND_SET
  (
    NRN                     in number,  -- Рег. номер запроса
    SCOND                   in varchar2 -- Условия отбора
  );

  /* Переключение флага подстановки значений аргументов запроса в SQL-выражение */
  procedure QUERY_OPT_SUBST_ARGS_VALS_TGL
  (
    NRN                     in number   -- Рег. номер запроса
  );

end PKG_P8PANELS_QE;
/
create or replace package body PKG_P8PANELS_QE as

  /* Константы - Минимальная длина поисковой фразы для сущностей */
  NENT_MIN_SEARCH_LEN       constant PKG_STD.TNUMBER := 3; -- Количество символов
  
  /* Получение списка доступных сущностей */
  procedure ENTITY_LIST
  (
    SSEARCH                 in varchar2, -- Поисковый запрос
    COUT                    out clob     -- Сериализованный список доступных сущностей
  )
  is
  begin
    /* Если фильтр задан и он нас утраивает */
    if ((SSEARCH is not null) and (LENGTH(SSEARCH) >= NENT_MIN_SEARCH_LEN)) then
      /* Получим список доступных сущностей */
      COUT := PKG_P8PANELS_QE_BASE.ENTITY_LIST(SSEARCH => SSEARCH, NBRIEF => 1, NINCLUDE_ATTRS => 0);
    end if;
  end ENTITY_LIST;
  
  /* Получение описания запроса */
  procedure QUERY
  (
    NRN                     in number,  -- Рег. номер запроса
    COUT                    out clob    -- Сериализованное описание запроса
  )
  is
  begin
    /* Проверим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_VIEW(NRN => NRN, SUSER => UTILIZER());
    /* Получим описание запроса */
    COUT := PKG_P8PANELS_QE_BASE.QUERY(NRN => NRN);
  end QUERY;
  
  /* Получение списка запросов */
  procedure QUERY_LIST
  (
    COUT                    out clob    -- Сериализованный список запросов
  )
  is
  begin
    /* Базово сформируем список */
    COUT := PKG_P8PANELS_QE_BASE.QUERY_LIST(SUSER => UTILIZER());
  end QUERY_LIST;
  
  /* Добавление запроса */
  procedure QUERY_INSERT
  (
    SCODE                   in varchar2, -- Мнемокод
    SNAME                   in varchar2, -- Наименование
    NRN                     out number   -- Рег. номер добавленного запроса
  )
  is
  begin
    /* Базовое добавление */
    PKG_P8PANELS_QE_BASE.QUERY_INSERT(SCODE => SCODE, SNAME => SNAME, NRN => NRN);
  end QUERY_INSERT;
  
  /* Исправление запроса */
  procedure QUERY_UPDATE
  (
    NRN                     in number,   -- Рег. номер запроса
    SCODE                   in varchar2, -- Мнемокод
    SNAME                   in varchar2  -- Наименование
  )
  is
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Базовое исправление */
    PKG_P8PANELS_QE_BASE.QUERY_UPDATE(NRN => NRN, SCODE => SCODE, SNAME => SNAME);
  end QUERY_UPDATE;

  /* Удаление запроса */
  procedure QUERY_DELETE
  (
    NRN                     in number   -- Рег. номер запроса
  )
  is
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Базовое удаление */
    PKG_P8PANELS_QE_BASE.QUERY_DELETE(NRN => NRN);
  end QUERY_DELETE;
  
  /* Установка признака "готовности" запроса */
  procedure QUERY_READY_SET
  (
    NRN                     in number,  -- Рег. номер запроса
    NREADY                  in number   -- Флаг готовности к использованию (0 - нет, 1 - да)
  )
  is
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Базовая установка признака готовности */
    PKG_P8PANELS_QE_BASE.QUERY_READY_SET(NRN => NRN, NREADY => NREADY);
  end QUERY_READY_SET;

  /* Установка признака "публичности" запроса */
  procedure QUERY_PBL_SET
  (
    NRN                     in number,  -- Рег. номер запроса
    NPBL                    in number   -- Флаг публичности (0 - приватный, 1 - публичный)
  )
  is
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Базовая установка признака публичности */
    PKG_P8PANELS_QE_BASE.QUERY_PBL_SET(NRN => NRN, NPBL => NPBL);
  end QUERY_PBL_SET;
  
  /* Добавление сущности в запрос */
  procedure QUERY_ENT_ADD
  (
    NRN                     in number,                  -- Рег. номер запроса
    SNAME                   in varchar2,                -- Имя
    STYPE                   in varchar2                 -- Тип (см. константы SENT_TYPE_*)
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;     -- Запись запроса
    RENTS                   PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем существующие сущности */
    RENTS := PKG_P8PANELS_QE_BASE.QUERY_ENTS_GET(CENTS => RQ.ENTS);
    /* Формируем описание новой сущности и добавляем её в коллекцию */
    PKG_P8PANELS_QE_BASE.TENTS_ADD(RENTS => RENTS, SNAME => SNAME, STYPE => STYPE);
    /* Сохраняем обновленный набор сущностей */
    PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_ENT_ADD;
  
  /* Удаление сущности из запроса */
  procedure QUERY_ENT_REMOVE
  (
    NRN                     in number,                  -- Рег. номер запроса
    SID                     in varchar2                 -- Идентификатор сущности
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;     -- Запись запроса
    RENTS                   PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
    RENT                    PKG_P8PANELS_QE_BASE.TENT;  -- Удаляемая сущность
    RRLS                    PKG_P8PANELS_QE_BASE.TRLS;  -- Коллекция существующих связей
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем существующие сущности */
    RENTS := PKG_P8PANELS_QE_BASE.QUERY_ENTS_GET(CENTS => RQ.ENTS);
    /* Читаем свзяи */
    RRLS := PKG_P8PANELS_QE_BASE.QUERY_RLS_GET(CRLS => RQ.RLS);
    /* Находим удаляемую сущность */
    begin
      RENT := RENTS(PKG_P8PANELS_QE_BASE.TENTS_INDEX_BY_ID(RENTS => RENTS, SID => SID));
    exception
      when VALUE_ERROR then
        P_EXCEPTION(0,
                    'Сущность с идентификатором "%s" в запросе "%s" не определена.',
                    COALESCE(SID, '<НЕ УКАЗАН>'),
                    TO_CHAR(NRN));
    end;
    /* Удаляем сущность из коллекции */
    PKG_P8PANELS_QE_BASE.TENTS_REMOVE(RENTS => RENTS, SID => SID);
    /* Обходим атрибуты сущности */
    if ((RENT.RATTRS is not null) and (RENT.RATTRS.COUNT > 0)) then
      for I in RENT.RATTRS.FIRST .. RENT.RATTRS.LAST
      loop
        /* Удаляем связи в которых он задействован */
        PKG_P8PANELS_QE_BASE.TRLS_CLEANUP_BY_ATTR(RRLS => RRLS, SATTR_ID => RENT.RATTRS(I).SID);
      end loop;
    end if;
    /* Сохраняем обновленный набор сущностей */
    PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
    /* Сохраняем обновленный набор связей */
    PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_ENT_REMOVE;
  
  /* Установка координат сущности в редакторе диаграммы запроса */
  procedure QUERY_ENT_POSITION_SET
  (
    NRN                     in number,                  -- Рег. номер запроса
    SID                     in varchar2,                -- Идентификатор сущности
    NX                      in number,                  -- Координата по оси абсцисс
    NY                      in number                   -- Координата по оси ординат
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;     -- Запись запроса
    RENTS                   PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
  begin
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Сохранять расположение будем только если это автор - так остальные могут перемещать на экране диаграмму, но не запоминать расположение сущностей */
    if (RQ.AUTHOR = UTILIZER()) then
      /* Читаем существующие сущности */
      RENTS := PKG_P8PANELS_QE_BASE.QUERY_ENTS_GET(CENTS => RQ.ENTS);
      /* Меняем координаты сущности в коллекции */
      PKG_P8PANELS_QE_BASE.TENTS_POSITION_SET(RENTS => RENTS, SID => SID, NX => NX, NY => NY);
      /* Сохраняем обновленный набор сущностей */
      PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
    end if;
  end QUERY_ENT_POSITION_SET;

  /* Получение состава атрибутов сущности */
  procedure QUERY_ENT_ATTRS_GET
  (
    NRN                     in number,   -- Рег. номер запроса
    SID                     in varchar2, -- Идентификатор сущности
    COUT                    out clob     -- Сериализованное описание атрибутов сущности
  )
  is
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Сформируем описание атрибутов */
    PKG_P8PANELS_QE_BASE.QUERY_ENT_ATTRS_GET(NRN => NRN, SID => SID, COUT => COUT);
  end QUERY_ENT_ATTRS_GET;
  
  /* Установка состава атрибутов сущности */
  procedure QUERY_ENT_ATTRS_SET
  (
    NRN                     in number,                   -- Рег. номер запроса
    SID                     in varchar2,                 -- Идентификатор сущности
    CATTRS                  in clob                      -- Сериализованное описание атрибутов сущности (BASE64 XML)
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;      -- Запись запроса
    RENTS                   PKG_P8PANELS_QE_BASE.TENTS;  -- Коллекция существующих сущностей
    NENT_INDEX              PKG_STD.TNUMBER;             -- Индекс изменяемой сущности
    RATTRS                  PKG_P8PANELS_QE_BASE.TATTRS; -- Коллекция полученных атриубтов
    RRLS                    PKG_P8PANELS_QE_BASE.TRLS;   -- Коллекция существующих связей
    SCHECK_MSG              PKG_STD.TLSTRING;            -- Сообщение при проверке атрибутов
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем существующие сущности */
    RENTS := PKG_P8PANELS_QE_BASE.QUERY_ENTS_GET(CENTS => RQ.ENTS);
    /* Читаем свзяи */
    RRLS := PKG_P8PANELS_QE_BASE.QUERY_RLS_GET(CRLS => RQ.RLS);
    /* Находим изменяемую сущность */
    NENT_INDEX := PKG_P8PANELS_QE_BASE.TENTS_INDEX_BY_ID(RENTS => RENTS, SID => SID);
    if (NENT_INDEX is null) then
      P_EXCEPTION(0,
                  'Сущность с идентификатором "%s" в запросе "%s" не определена.',
                  COALESCE(SID, '<НЕ УКАЗАН>'),
                  TO_CHAR(NRN));
    end if;
    /* Десериализуем новый набор атрибутов */
    RATTRS := PKG_P8PANELS_QE_BASE.TATTRS_FROM_XML_BASE64(CXML      => CATTRS,
                                                          SCHARSET  => PKG_CHARSET.CHARSET_UTF_(),
                                                          BADD_ROOT => true);
    /* Сбросим текущие атрибуты сущности */
    RENTS(NENT_INDEX).RATTRS := PKG_P8PANELS_QE_BASE.TATTRS();
    /* Наполним полученными и зачистим связи */
    if (RATTRS is not null) and (RATTRS.COUNT > 0) then
      for I in RATTRS.FIRST .. RATTRS.LAST
      loop
        /* Если атрибут используется - кладём в обновленную коллекцию атрибутов сущности */
        if (RATTRS(I).NUSE = 1) then
          RENTS(NENT_INDEX).RATTRS.EXTEND();
          RENTS(NENT_INDEX).RATTRS(RENTS(NENT_INDEX).RATTRS.LAST) := RATTRS(I);
        else
          /* Атрибут не используется - необходимо очистись связи в которых он задействован */
          PKG_P8PANELS_QE_BASE.TRLS_CLEANUP_BY_ATTR(RRLS => RRLS, SATTR_ID => RATTRS(I).SID);
        end if;
      end loop;
    end if;
    /* Проверим, что новый набор атрибутов сущности корректен */
    PKG_P8PANELS_QE_BASE.TATTRS_CHECK(RATTRS => RENTS(NENT_INDEX).RATTRS, SCHECK_MSG => SCHECK_MSG);
    if (SCHECK_MSG is not null) then
      P_EXCEPTION(0, SCHECK_MSG);
    end if;
    /* Сохраняем обновленный набор сущностей */
    PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
    /* Сохраняем обновленный набор связей */
    PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_ENT_ATTRS_SET;

  /* Добавление связи в запрос */
  procedure QUERY_RL_ADD
  (
    NRN                     in number,                 -- Рег. номер запроса
    SSOURCE                 in varchar2,               -- Идентификатор атрибута-источника
    STARGET                 in varchar2                -- Идентификатор атрибута-приёмника
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;    -- Запись запроса
    RRLS                    PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем существующие связи */
    RRLS := PKG_P8PANELS_QE_BASE.QUERY_RLS_GET(CRLS => RQ.RLS);
    /* Формируем описание новой связи и добавляем её в коллекцию */
    PKG_P8PANELS_QE_BASE.TRLS_ADD(RRLS => RRLS, SSOURCE => SSOURCE, STARGET => STARGET, NMANDATORY => 0);
    /* Сохраняем обновленный набор связей */
    PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_RL_ADD;
  
  /* Удаление связи из запроса */
  procedure QUERY_RL_REMOVE
  (
    NRN                     in number,                 -- Рег. номер запроса
    SID                     in varchar2                -- Идентификатор связи
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;    -- Запись запроса
    RRLS                    PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем существующие связи */
    RRLS := PKG_P8PANELS_QE_BASE.QUERY_RLS_GET(CRLS => RQ.RLS);
    /* Удаляем связи из коллекции */
    PKG_P8PANELS_QE_BASE.TRLS_REMOVE(RRLS => RRLS, SID => SID);
    /* Сохраняем обновленный набор связей */
    PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_RL_REMOVE;
  
  /* Установка признака обязательности связи */
  procedure QUERY_RL_MANDATORY_SET
  (
    NRN                     in number,                 -- Рег. номер запроса
    SID                     in varchar2,               -- Идентификатор связи
    NMANDATORY              in number                  -- Флаг обязательности (1 - да, 0 - нет)
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;    -- Запись запроса
    RRLS                    PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
  begin
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем существующие связи */
    RRLS := PKG_P8PANELS_QE_BASE.QUERY_RLS_GET(CRLS => RQ.RLS);
    /* Устанавливаем признакобязательности */
    PKG_P8PANELS_QE_BASE.TRLS_MANDATORY_SET(RRLS => RRLS, SID => SID, NMANDATORY => NMANDATORY);
    /* Сохраняем обновленный набор связей */
    PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_RL_MANDATORY_SET;
  
  /* Добавление аргумента запроса */
  procedure QUERY_OPT_ARG_ADD
  (
    NRN                     in number,                 -- Рег. номер запроса
    SNAME                   in varchar2,               -- Имя
    STITLE                  in varchar2,               -- Заголовок
    NDATA_TYPE              in number,                 -- Тип данных (см. константы PKG_STD.DATA_TYPE_*)
    NMANDATORY              in number,                 -- Флаг обязательности (1 - да, 0 - нет)
    SVALUE                  in varchar2                -- Значение для отладки (строковое представление для всех типов данных)
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;    -- Запись запроса
    ROPT                    PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем текущую настройку */
    ROPT := PKG_P8PANELS_QE_BASE.QUERY_OPT_GET(COPT => RQ.OPT);
    /* Добавляем аргумент в коллекцию */
    PKG_P8PANELS_QE_BASE.TARGS_ADD(RARGS      => ROPT.RARGS,
                                   SNAME      => SNAME,
                                   STITLE     => STITLE,
                                   NDATA_TYPE => NDATA_TYPE,
                                   NMANDATORY => NMANDATORY,
                                   SVALUE     => SVALUE);
    /* Сохраняем обновленную настройку */
    PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_OPT_ARG_ADD;
  
  /* Изменение аргумента запроса */
  procedure QUERY_OPT_ARG_EDIT
  (
    NRN                     in number,                 -- Рег. номер запроса
    SNAME                   in varchar2,               -- Имя
    STITLE                  in varchar2,               -- Заголовок
    NDATA_TYPE              in number,                 -- Тип данных (см. константы PKG_STD.DATA_TYPE_*)
    NMANDATORY              in number,                 -- Флаг обязательности (1 - да, 0 - нет)
    SVALUE                  in varchar2                -- Значение для отладки (строковое представление для всех типов данных)
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;    -- Запись запроса
    ROPT                    PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса
    NINDEX                  PKG_STD.TNUMBER;           -- Индекс изменяемого аргумента в коллекции
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем текущую настройку */
    ROPT := PKG_P8PANELS_QE_BASE.QUERY_OPT_GET(COPT => RQ.OPT);
    /* Находим изменяемый аргумент */
    NINDEX := PKG_P8PANELS_QE_BASE.TARGS_INDEX_BY_NAME(RARGS => ROPT.RARGS, SNAME => SNAME);
    if (NINDEX is null) then
      P_EXCEPTION(0,
                  'Аргумент с именем "%s" в запросе "%s" не определен.',
                  COALESCE(SNAME, '<НЕ УКАЗАН>'),
                  TO_CHAR(NRN));
    end if;
    /* Изменяем аргумент в коллекции */
    PKG_P8PANELS_QE_BASE.TARGS_EDIT(RARGS      => ROPT.RARGS,
                                    NINDEX     => NINDEX,
                                    SNAME      => SNAME,
                                    STITLE     => STITLE,
                                    NDATA_TYPE => NDATA_TYPE,
                                    NMANDATORY => NMANDATORY,
                                    SVALUE     => SVALUE);
    /* Сохраняем обновленную настройку */
    PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_OPT_ARG_EDIT;
  
  /* Удаление аргумента запроса */
  procedure QUERY_OPT_ARG_REMOVE
  (
    NRN                     in number,                 -- Рег. номер запроса
    SNAME                   in varchar2                -- Имя
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;    -- Запись запроса
    ROPT                    PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем текущую настройку */
    ROPT := PKG_P8PANELS_QE_BASE.QUERY_OPT_GET(COPT => RQ.OPT);
    /* Находим удаляемый аргумент */
    if (PKG_P8PANELS_QE_BASE.TARGS_INDEX_BY_NAME(RARGS => ROPT.RARGS, SNAME => SNAME) is null) then
      P_EXCEPTION(0,
                  'Аргумент с именем "%s" в запросе "%s" не определен.',
                  COALESCE(SNAME, '<НЕ УКАЗАН>'),
                  TO_CHAR(NRN));
    end if;
    /* Удаляем аргумент из коллекции */
    PKG_P8PANELS_QE_BASE.TARGS_REMOVE(RARGS => ROPT.RARGS, SNAME => SNAME);
    /* Сохраняем обновленную настройку */
    PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_OPT_ARG_REMOVE;
  
  /* Установка условий отбора запроса */
  procedure QUERY_OPT_COND_SET
  (
    NRN                     in number,                 -- Рег. номер запроса
    SCOND                   in varchar2                -- Условия отбора
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;    -- Запись запроса
    ROPT                    PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем текущую настройку */
    ROPT := PKG_P8PANELS_QE_BASE.QUERY_OPT_GET(COPT => RQ.OPT);
    /* Установим новые условия отбора */
    ROPT.SCOND := SCOND;
    /* Сохраняем обновленную настройку */
    PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_OPT_COND_SET;
  
  /* Переключение флага подстановки значений аргументов запроса в SQL-выражение */
  procedure QUERY_OPT_SUBST_ARGS_VALS_TGL
  (
    NRN                     in number                  -- Рег. номер запроса
  )
  is
    RQ                      P8PNL_QE_QUERY%rowtype;    -- Запись запроса
    ROPT                    PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса
  begin
    /* Провим права доступа */
    PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
    /* Читаем запись запроса */
    RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
    /* Читаем текущую настройку */
    ROPT := PKG_P8PANELS_QE_BASE.QUERY_OPT_GET(COPT => RQ.OPT);
    /* Установим новый флаг подстановки значений аргументов в запрос */
    if (ROPT.NSUBST_ARGS_VALS = 1) then
      ROPT.NSUBST_ARGS_VALS := 0;
    else
      ROPT.NSUBST_ARGS_VALS := 1;
    end if;
    /* Сохраняем обновленную настройку */
    PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT);
    /* Переформируем SQL-выражение */
    PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN);
  end QUERY_OPT_SUBST_ARGS_VALS_TGL;
  
end PKG_P8PANELS_QE;
/
