From abaf9455a90ed061a6401f49ae41d3cae27e2a7e Mon Sep 17 00:00:00 2001 From: Mikhail Chechnev Date: Fri, 22 Aug 2025 13:39:42 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A6=D0=98=D0=A2=D0=9A-979=20-=20=D0=9D=D0=B0?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=81=D0=B0=20-=20=D0=B0=D1=80=D0=B3=D1=83=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D1=8B=20(=D1=81=D0=B5=D1=80=D0=B2=D0=B5?= =?UTF-8?q?=D1=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/P8PNL_QE_QUERY.sql | 2 +- db/PKG_P8PANELS_QE.pck | 200 ++++++++-- db/PKG_P8PANELS_QE_BASE.pck | 753 ++++++++++++++++++++++++++++++------ 3 files changed, 803 insertions(+), 152 deletions(-) diff --git a/db/P8PNL_QE_QUERY.sql b/db/P8PNL_QE_QUERY.sql index 318bc7d..0eacf2c 100644 --- a/db/P8PNL_QE_QUERY.sql +++ b/db/P8PNL_QE_QUERY.sql @@ -11,7 +11,7 @@ create table P8PNL_QE_QUERY CH_DATE date not null, -- Дата последнего изменения READY number(1) default 0 not null, -- Флаг готовности к использованию (0 - нет, 1 - да) PBL number(1) default 0 not null, -- Флаг публичности (0 - нет, 1 - да) - OPTS clob, -- Параметры запроса + OPT clob, -- Настройка запроса ENTS clob, -- Сущности запроса RLS clob, -- Отношения сущностей запроса QRY clob, -- Запрос diff --git a/db/PKG_P8PANELS_QE.pck b/db/PKG_P8PANELS_QE.pck index 6fb9d72..36c9bc5 100644 --- a/db/PKG_P8PANELS_QE.pck +++ b/db/PKG_P8PANELS_QE.pck @@ -1,11 +1,18 @@ create or replace package PKG_P8PANELS_QE as + /* Получение данных о запросе */ + procedure QUERY + ( + NRN in number, -- Рег. номер запроса + COUT out clob -- Сериализованное описание запроса + ); + /* Получение списка запросов */ procedure QUERY_LIST ( COUT out clob -- Сериализованный список запросов ); - + /* Добавление запроса */ procedure QUERY_INSERT ( @@ -28,11 +35,18 @@ create or replace package PKG_P8PANELS_QE as NRN in number -- Рег. номер запроса ); - /* Получение данных о запросе */ - procedure QUERY_DESC + /* Установка признака "готовности" запроса */ + procedure QUERY_READY_SET ( NRN in number, -- Рег. номер запроса - COUT out clob -- Сериализованное описание запроса + NREADY in number -- Флаг готовности к использованию (0 - нет, 1 - да) + ); + + /* Установка признака "публичности" запроса */ + procedure QUERY_PBL_SET + ( + NRN in number, -- Рег. номер запроса + NPBL in number -- Флаг публичности (0 - приватный, 1 - публичный) ); /* Добавление сущности в запрос */ @@ -90,24 +104,51 @@ create or replace package PKG_P8PANELS_QE as SID in varchar2 -- Идентификатор связи ); - /* Установка признака "готовности" запроса */ - procedure QUERY_READY_SET + /* Добавление аргумента запроса */ + procedure QUERY_OPT_ARG_ADD ( - NRN in number, -- Рег. номер запроса - NREADY in number -- Флаг готовности к использованию (0 - нет, 1 - да) + NRN in number, -- Рег. номер запроса + SNAME in varchar2, -- Имя + STITLE in varchar2, -- Заголовок + NDATA_TYPE in number, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY in number -- Флаг обязательности (1 - да, 0 - нет) ); - - /* Установка признака "публичности" запроса */ - procedure QUERY_PBL_SET + + /* Изменение аргумента запроса */ + 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 - нет) + ); + + /* Удаление аргумента запроса */ + procedure QUERY_OPT_ARG_REMOVE ( NRN in number, -- Рег. номер запроса - NPBL in number -- Флаг публичности (0 - приватный, 1 - публичный) + SNAME in varchar2 -- Имя ); end PKG_P8PANELS_QE; / create or replace package body PKG_P8PANELS_QE as + /* Получение описания запроса */ + 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 ( @@ -116,7 +157,7 @@ create or replace package body PKG_P8PANELS_QE as is begin /* Базово сформируем список */ - COUT := PKG_P8PANELS_QE_BASE.QUERY_LIST_GET(SUSER => UTILIZER()); + COUT := PKG_P8PANELS_QE_BASE.QUERY_LIST(SUSER => UTILIZER()); end QUERY_LIST; /* Добавление запроса */ @@ -160,19 +201,33 @@ create or replace package body PKG_P8PANELS_QE as PKG_P8PANELS_QE_BASE.QUERY_DELETE(NRN => NRN); end QUERY_DELETE; - /* Получение описания запроса */ - procedure QUERY_DESC + /* Установка признака "готовности" запроса */ + procedure QUERY_READY_SET ( NRN in number, -- Рег. номер запроса - COUT out clob -- Сериализованное описание запроса + NREADY in number -- Флаг готовности к использованию (0 - нет, 1 - да) ) is begin - /* Проверим права доступа */ - PKG_P8PANELS_QE_BASE.QUERY_ACCESS_VIEW(NRN => NRN, SUSER => UTILIZER()); - /* Получим описание запроса */ - COUT := PKG_P8PANELS_QE_BASE.QUERY_DESC_GET(NRN => NRN); - end QUERY_DESC; + /* Провим права доступа */ + 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 @@ -192,7 +247,7 @@ create or replace package body PKG_P8PANELS_QE as /* Читаем существующие сущности */ RENTS := PKG_P8PANELS_QE_BASE.QUERY_ENTS_GET(CENTS => RQ.ENTS); /* Формируем описание новой сущности и добавляем её в коллекцию */ - PKG_P8PANELS_QE_BASE.TENTS_APPEND(RENTS => RENTS, SNAME => SNAME, STYPE => STYPE); + PKG_P8PANELS_QE_BASE.TENTS_ADD(RENTS => RENTS, SNAME => SNAME, STYPE => STYPE); /* Сохраняем обновленный набор сущностей */ PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS); end QUERY_ENT_ADD; @@ -357,7 +412,7 @@ create or replace package body PKG_P8PANELS_QE as /* Читаем существующие связи */ RRLS := PKG_P8PANELS_QE_BASE.QUERY_RLS_GET(CRLS => RQ.RLS); /* Формируем описание новой связи и добавляем её в коллекцию */ - PKG_P8PANELS_QE_BASE.TRLS_APPEND(RRLS => RRLS, SSOURCE => SSOURCE, STARGET => STARGET); + PKG_P8PANELS_QE_BASE.TRLS_ADD(RRLS => RRLS, SSOURCE => SSOURCE, STARGET => STARGET); /* Сохраняем обновленный набор связей */ PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS); end QUERY_RL_ADD; @@ -384,33 +439,102 @@ create or replace package body PKG_P8PANELS_QE as PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS); end QUERY_RL_REMOVE; - /* Установка признака "готовности" запроса */ - procedure QUERY_READY_SET + /* Добавление аргумента запроса */ + procedure QUERY_OPT_ARG_ADD ( - NRN in number, -- Рег. номер запроса - NREADY in number -- Флаг готовности к использованию (0 - нет, 1 - да) + NRN in number, -- Рег. номер запроса + SNAME in varchar2, -- Имя + STITLE in varchar2, -- Заголовок + NDATA_TYPE in number, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY in number -- Флаг обязательности (1 - да, 0 - нет) ) is + RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса + ROPT PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса 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 + /* Читаем запись запроса */ + 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); + /* Сохраняем обновленную настройку */ + PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT); + end QUERY_OPT_ARG_ADD; + + /* Изменение аргумента запроса */ + procedure QUERY_OPT_ARG_EDIT ( - NRN in number, -- Рег. номер запроса - NPBL in number -- Флаг публичности (0 - приватный, 1 - публичный) + NRN in number, -- Рег. номер запроса + SNAME in varchar2, -- Имя + STITLE in varchar2, -- Заголовок + NDATA_TYPE in number, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY in number -- Флаг обязательности (1 - да, 0 - нет) ) 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()); - /* Базовая установка признака публичности */ - PKG_P8PANELS_QE_BASE.QUERY_PBL_SET(NRN => NRN, NPBL => NPBL); - end QUERY_PBL_SET; + /* Читаем запись запроса */ + 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); + /* Сохраняем обновленную настройку */ + PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT); + 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); + end QUERY_OPT_ARG_REMOVE; end PKG_P8PANELS_QE; / diff --git a/db/PKG_P8PANELS_QE_BASE.pck b/db/PKG_P8PANELS_QE_BASE.pck index 3108a63..a57aa9c 100644 --- a/db/PKG_P8PANELS_QE_BASE.pck +++ b/db/PKG_P8PANELS_QE_BASE.pck @@ -1,5 +1,24 @@ create or replace package PKG_P8PANELS_QE_BASE as + /* Типы данных - Аргумент */ + type TARG is record + ( + SNAME PKG_STD.TSTRING, -- Имя + STITLE PKG_STD.TSTRING, -- Заголовок + NDATA_TYPE PKG_STD.TNUMBER, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY PKG_STD.TNUMBER -- Флаг обязательности (1 - да, 0 - нет) + ); + + /* Типы данных - Коллекция аргументов */ + type TARGS is table of TARG; + + /* Типы данных - Настройка запроса */ + type TOPT is record + ( + RARGS TARGS, -- Аргументы + SCOND PKG_STD.TSTRING -- Условия отбора + ); + /* Типы данных - Атрибут сущности */ type TATTR is record ( @@ -50,6 +69,41 @@ create or replace package PKG_P8PANELS_QE_BASE as BADD_ROOT in boolean := false -- Флаг необходимости добавления корневого тэга (false - нет, true - да) ) return TATTRS; -- Коллекция атрибутов сущности + /* Поиск индекса аргумента по имени */ + function TARGS_INDEX_BY_NAME + ( + RARGS in TARGS, -- Коллекция аргументов + SNAME in varchar2 -- Искомое имя + ) return number; -- Индекс найденного аргумента (null - если не найдено) + + /* Добавление аргумента в коллекцию */ + procedure TARGS_ADD + ( + RARGS in out nocopy TARGS, -- Изменяемая коллекция + SNAME in varchar2, -- Имя + STITLE in varchar2, -- Заголовок + NDATA_TYPE in number, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY in number -- Флаг обязательности (1 - да, 0 - нет) + ); + + /* Изменение аргумента в коллекции */ + procedure TARGS_EDIT + ( + RARGS in out nocopy TARGS, -- Изменяемая коллекция + NINDEX in number, -- Индекс изменяемого аргумента + SNAME in varchar2, -- Имя + STITLE in varchar2, -- Заголовок + NDATA_TYPE in number, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY in number -- Флаг обязательности (1 - да, 0 - нет) + ); + + /* Удаление аргумента из коллекции */ + procedure TARGS_REMOVE + ( + RARGS in out nocopy TARGS, -- Изменяемая коллекция + SNAME in varchar2 -- Имя удаляемого аргумента + ); + /* Поиск индекса сущности по идентификатору */ function TENTS_INDEX_BY_ID ( @@ -58,7 +112,7 @@ create or replace package PKG_P8PANELS_QE_BASE as ) return number; -- Индекс найденной сущности (null - если не найдено) /* Добавление сущности в коллекцию */ - procedure TENTS_APPEND + procedure TENTS_ADD ( RENTS in out nocopy TENTS, -- Изменяемая коллекция SNAME in varchar2, -- Имя @@ -82,7 +136,7 @@ create or replace package PKG_P8PANELS_QE_BASE as ); /* Добавление связи в коллекцию */ - procedure TRLS_APPEND + procedure TRLS_ADD ( RRLS in out nocopy TRLS, -- Изменяемая коллекция SSOURCE in varchar2, -- Источник @@ -109,7 +163,7 @@ create or replace package PKG_P8PANELS_QE_BASE as NRN in number -- Рег. номер запроса ) return P8PNL_QE_QUERY%rowtype; -- Запись запроса - /* Получение признака возможности изменения запроса */ + /* Получение признака возможности изменения запроса */ function QUERY_ACCESS_SIGN_MODIFY ( NRN in number, -- Рег. номер запроса @@ -136,7 +190,19 @@ create or replace package PKG_P8PANELS_QE_BASE as NRN in number, -- Рег. номер запроса SUSER in varchar2 -- Имя пользователя ); - + + /* Формирование описания запроса */ + function QUERY + ( + NRN in number -- Рег. номер запроса + ) return clob; -- XML-описание + + /* Формирование списка запросов */ + function QUERY_LIST + ( + SUSER in varchar2 -- Имя пользователя + ) return clob; -- Список запросов + /* Добавление запроса */ procedure QUERY_INSERT ( @@ -159,18 +225,6 @@ create or replace package PKG_P8PANELS_QE_BASE as NRN in number -- Рег. номер запроса ); - /* Формирование списка запросов */ - function QUERY_LIST_GET - ( - SUSER in varchar2 -- Имя пользователя - ) return clob; -- Список запросов - - /* Получение описания запроса */ - function QUERY_DESC_GET - ( - NRN in number -- Рег. номер запроса - ) return clob; -- XML-описание - /* Чтение сущностей запроса */ function QUERY_ENTS_GET ( @@ -219,6 +273,19 @@ create or replace package PKG_P8PANELS_QE_BASE as NPBL in number -- Флаг публичности (0 - приватный, 1 - публичный) ); + /* Чтение настройки запроса */ + function QUERY_OPT_GET + ( + COPT in clob -- Сериализованное описание настройки запроса + ) return TOPT; -- Настройка запроса + + /* Запись настройки запроса */ + procedure QUERY_OPT_SET + ( + NRN in number, -- Рег. номер запроса + ROPT in TOPT -- Настройка запроса + ); + end PKG_P8PANELS_QE_BASE; / create or replace package body PKG_P8PANELS_QE_BASE as @@ -231,36 +298,43 @@ create or replace package body PKG_P8PANELS_QE_BASE as STAG_DATA constant PKG_STD.TSTRING := 'XDATA'; -- Данные STAG_QUERIES constant PKG_STD.TSTRING := 'XQUERIES'; -- Запросы STAG_QUERY constant PKG_STD.TSTRING := 'XQUERY'; -- Запрос + STAG_ARGS constant PKG_STD.TSTRING := 'XARGS'; -- Аргументы запроса + STAG_ARG constant PKG_STD.TSTRING := 'XARG'; -- Аргумент запроса STAG_ATTRS constant PKG_STD.TSTRING := 'XATTRS'; -- Атрибуты сущности STAG_ATTR constant PKG_STD.TSTRING := 'XATTR'; -- Атрибут сущности STAG_ENTS constant PKG_STD.TSTRING := 'XENTS'; -- Сущности STAG_ENT constant PKG_STD.TSTRING := 'XENT'; -- Сущность STAG_RLS constant PKG_STD.TSTRING := 'XRLS'; -- Связи STAG_RL constant PKG_STD.TSTRING := 'XRL'; -- Связь - STAG_OPTS constant PKG_STD.TSTRING := 'XOPTS'; -- Параметры - STAG_OPT constant PKG_STD.TSTRING := 'XOPT'; -- Параметр + STAG_OPT constant PKG_STD.TSTRING := 'XOPT'; -- Настройка запроса + STAG_COND constant PKG_STD.TSTRING := 'XCOND'; -- Условия запроса /* Константы - Атрибуты для сериализации */ - SATTR_ID constant PKG_STD.TSTRING := 'id'; -- Идентификатор - SATTR_RN constant PKG_STD.TSTRING := 'rn'; -- Регистрационный номер - SATTR_CODE constant PKG_STD.TSTRING := 'code'; -- Код - SATTR_NAME constant PKG_STD.TSTRING := 'name'; -- Имя - SATTR_AUTHOR constant PKG_STD.TSTRING := 'author'; -- Автор - SATTR_CH_DATE constant PKG_STD.TSTRING := 'chDate'; -- Дата изменения - SATTR_READY constant PKG_STD.TSTRING := 'ready'; -- Готовность к использованию - SATTR_PBL constant PKG_STD.TSTRING := 'pbl'; -- Публичность - SATTR_MODIFY constant PKG_STD.TSTRING := 'modify'; -- Изменяемость - SATTR_TITLE constant PKG_STD.TSTRING := 'title'; -- Заголовок - SATTR_TYPE constant PKG_STD.TSTRING := 'type'; -- Тип - SATTR_DATA_TYPE constant PKG_STD.TSTRING := 'dataType'; -- Тип данных - SATTR_X constant PKG_STD.TSTRING := 'x'; -- Координата по X - SATTR_Y constant PKG_STD.TSTRING := 'y'; -- Координата по Y - SATTR_SOURCE constant PKG_STD.TSTRING := 'source'; -- Источник - SATTR_TARGET constant PKG_STD.TSTRING := 'target'; -- Приёмник - SATTR_AGG constant PKG_STD.TSTRING := 'agg'; -- Агрегатная функция - SATTR_ALIAS constant PKG_STD.TSTRING := 'alias'; -- Псевдоним - SATTR_USE constant PKG_STD.TSTRING := 'use'; -- Применение в запросе - SATTR_SHOW constant PKG_STD.TSTRING := 'show'; -- Отображение в запросе + SATTR_ID constant PKG_STD.TSTRING := 'id'; -- Идентификатор + SATTR_RN constant PKG_STD.TSTRING := 'rn'; -- Регистрационный номер + SATTR_CODE constant PKG_STD.TSTRING := 'code'; -- Код + SATTR_NAME constant PKG_STD.TSTRING := 'name'; -- Имя + SATTR_AUTHOR constant PKG_STD.TSTRING := 'author'; -- Автор + SATTR_CH_DATE constant PKG_STD.TSTRING := 'chDate'; -- Дата изменения + SATTR_READY constant PKG_STD.TSTRING := 'ready'; -- Готовность к использованию + SATTR_PBL constant PKG_STD.TSTRING := 'pbl'; -- Публичность + SATTR_MODIFY constant PKG_STD.TSTRING := 'modify'; -- Изменяемость + SATTR_TITLE constant PKG_STD.TSTRING := 'title'; -- Заголовок + SATTR_TYPE constant PKG_STD.TSTRING := 'type'; -- Тип + SATTR_DATA_TYPE constant PKG_STD.TSTRING := 'dataType'; -- Тип данных + SATTR_MANDATORY constant PKG_STD.TSTRING := 'mandatory'; -- Обязательность + SATTR_X constant PKG_STD.TSTRING := 'x'; -- Координата по X + SATTR_Y constant PKG_STD.TSTRING := 'y'; -- Координата по Y + SATTR_SOURCE constant PKG_STD.TSTRING := 'source'; -- Источник + SATTR_TARGET constant PKG_STD.TSTRING := 'target'; -- Приёмник + SATTR_AGG constant PKG_STD.TSTRING := 'agg'; -- Агрегатная функция + SATTR_ALIAS constant PKG_STD.TSTRING := 'alias'; -- Псевдоним + SATTR_USE constant PKG_STD.TSTRING := 'use'; -- Применение в запросе + SATTR_SHOW constant PKG_STD.TSTRING := 'show'; -- Отображение в запросе + + /* Константы - зарезервированные имена рагументов */ + SARG_NAME_PAGE constant PKG_STD.TSTRING := 'NPAGE'; -- Номер страницы + SARG_NAME_PAGE_SIZE constant PKG_STD.TSTRING := 'NPAGE_SIZE'; -- Размер страницы (записей) /* Получение заголовка представления из метаданных */ function DMSCLVIEWS_TITLE_GET @@ -317,6 +391,351 @@ create or replace package body PKG_P8PANELS_QE_BASE as return SATTR_NAME; end DMSCLVIEWSATTRS_TITLE_GET; + /* Формирование аргумента */ + function TARG_MAKE + ( + SNAME in varchar2, -- Имя + STITLE in varchar2, -- Заголовок + NDATA_TYPE in number, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY in number -- Флаг обязательности (1 - да, 0 - нет) + ) return TARG -- Описание аргумента + is + RARG TARG; -- Буфер для результата + begin + /* Проверим имя */ + if (SNAME is null) then + P_EXCEPTION(0, 'Имя аргумента не указано.'); + end if; + for C in (select null from DUAL where not REGEXP_LIKE(SNAME, '^[A-z0-9_]+$')) + loop + P_EXCEPTION(0, + 'Имя аргумента содержит недопустимые символы (разрешены латинские буквы, цифры и символ нижнего подчеркивания).'); + end loop; + if (UPPER(SNAME) in (UPPER(SARG_NAME_PAGE), UPPER(SARG_NAME_PAGE_SIZE))) then + P_EXCEPTION(0, 'Это имя аргумента зарезервировано Системой.'); + end if; + /* Проверим заголовок */ + if (STITLE is null) then + P_EXCEPTION(0, 'Не указан заголовок аргумента.'); + end if; + /* Проверим корректность типа сущности */ + if (NDATA_TYPE is null) then + P_EXCEPTION(0, 'Не указан тип данных аргумента.'); + end if; + if (NDATA_TYPE not in (PKG_STD.DATA_TYPE_STR, PKG_STD.DATA_TYPE_NUM, PKG_STD.DATA_TYPE_DATE)) then + P_EXCEPTION(0, + 'Аргументы типа "%s" не поддерживаются.', + COALESCE(TO_CHAR(NDATA_TYPE), '<НЕ УКАЗАН>')); + end if; + /* Проверим корректность флага обязательности */ + if (NMANDATORY is null) then + P_EXCEPTION(0, 'Не указан признак обязательности аргумента.'); + end if; + if (NMANDATORY not in (0, 1)) then + P_EXCEPTION(0, + 'Некорректно указан признак обязательности аргумента.'); + end if; + /* Собираем аргумент */ + RARG.SNAME := UPPER(SNAME); + RARG.STITLE := STITLE; + RARG.NDATA_TYPE := NDATA_TYPE; + RARG.NMANDATORY := NMANDATORY; + /* Вернем полученное */ + return RARG; + end TARG_MAKE; + + /* Сериализация аргумента */ + procedure TARG_TO_XML + ( + RARG in TARG -- Аргумент + ) + is + begin + /* Открываем описание аргумента */ + PKG_XFAST.DOWN_NODE(SNAME => STAG_ARG); + /* Аргумент */ + PKG_XFAST.ATTR(SNAME => SATTR_NAME, SVALUE => RARG.SNAME); + PKG_XFAST.ATTR(SNAME => SATTR_TITLE, SVALUE => RARG.STITLE); + PKG_XFAST.ATTR(SNAME => SATTR_DATA_TYPE, NVALUE => RARG.NDATA_TYPE); + PKG_XFAST.ATTR(SNAME => SATTR_MANDATORY, NVALUE => RARG.NMANDATORY); + /* Закрываем описание аргумента */ + PKG_XFAST.UP(); + end TARG_TO_XML; + + /* Десериализация аргумента */ + function TARG_FROM_XML + ( + CXML in clob -- XML-описание аргумента + ) return TARG -- Аргумент + is + RRES TARG; -- Буфер для результата + XDOC PKG_XPATH.TDOCUMENT; -- Документ XML + XROOT PKG_XPATH.TNODE; -- Корень документа XML + XNODE PKG_XPATH.TNODE; -- Буфер узла документа + begin + /* Если данные есть */ + if (CXML is not null) then + begin + /* Разбираем XML */ + XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); + /* Считываем корневой узел */ + XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); + XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => '/' || STAG_ARG); + /* Получаем значения */ + RRES.SNAME := PKG_XPATH.ATTRIBUTE(RNODE => XNODE, SNAME => SATTR_NAME); + RRES.STITLE := PKG_XPATH.ATTRIBUTE(RNODE => XNODE, SNAME => SATTR_TITLE); + RRES.NDATA_TYPE := PKG_XPATH.ATTRIBUTE_NUM(RNODE => XNODE, SNAME => SATTR_DATA_TYPE); + RRES.NMANDATORY := PKG_XPATH.ATTRIBUTE_NUM(RNODE => XNODE, SNAME => SATTR_MANDATORY); + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + exception + when others then + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + /* Вернем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end; + end if; + /* Вернём результат */ + return RRES; + end TARG_FROM_XML; + + /* Поиск индекса аргумента по имени */ + function TARGS_INDEX_BY_NAME + ( + RARGS in TARGS, -- Коллекция аргументов + SNAME in varchar2 -- Искомое имя + ) return number -- Индекс найденного аргумента (null - если не найдено) + is + begin + /* Обходим коллекцию */ + if ((RARGS is not null) and (RARGS.COUNT > 0)) then + for I in RARGS.FIRST .. RARGS.LAST + loop + begin + /* Возвращаем найденный индекс */ + if (RARGS(I).SNAME = SNAME) then + return I; + end if; + exception + when NO_DATA_FOUND then + null; + end; + end loop; + end if; + /* Ничего не нашли */ + return null; + end TARGS_INDEX_BY_NAME; + + /* Добавление аргумента в коллекцию */ + procedure TARGS_ADD + ( + RARGS in out nocopy TARGS, -- Изменяемая коллекция + SNAME in varchar2, -- Имя + STITLE in varchar2, -- Заголовок + NDATA_TYPE in number, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY in number -- Флаг обязательности (1 - да, 0 - нет) + ) + is + RARG TARG; -- Добавляемый аргумент + begin + /* Инициализируем коллекцию если необходимо */ + if (RARGS is null) then + RARGS := TARGS(); + end if; + /* Проверим уникальность имени */ + if ((SNAME is not null) and (TARGS_INDEX_BY_NAME(RARGS => RARGS, SNAME => SNAME) is not null)) then + P_EXCEPTION(0, 'Аргумент с именем "%s" уже существует.', SNAME); + end if; + /* Формируем аргумент */ + RARG := TARG_MAKE(SNAME => SNAME, STITLE => STITLE, NDATA_TYPE => NDATA_TYPE, NMANDATORY => NMANDATORY); + /* Добавляем его в коллекцию */ + RARGS.EXTEND(); + RARGS(RARGS.LAST) := RARG; + end TARGS_ADD; + + /* Изменение аргумента в коллекции */ + procedure TARGS_EDIT + ( + RARGS in out nocopy TARGS, -- Изменяемая коллекция + NINDEX in number, -- Индекс изменяемого аргумента + SNAME in varchar2, -- Имя + STITLE in varchar2, -- Заголовок + NDATA_TYPE in number, -- Тип данных (см. константы PKG_STD.DATA_TYPE_*) + NMANDATORY in number -- Флаг обязательности (1 - да, 0 - нет) + ) + is + RARG TARG; -- Добавляемый аргумент + begin + /* Проверим коллекцию */ + if ((RARGS is null) or (RARGS.COUNT = 0)) then + P_EXCEPTION(0, + 'Коллекция аргументов пуста. Изменение аргумента невозможно.'); + end if; + /* Проверим индекс изменяемого аргумента */ + if (NINDEX is null) then + P_EXCEPTION(0, 'Не указан индекс изменяемого аргумента.'); + end if; + /* Формируем аргумент */ + RARG := TARG_MAKE(SNAME => SNAME, STITLE => STITLE, NDATA_TYPE => NDATA_TYPE, NMANDATORY => NMANDATORY); + /* Обновляем аргумент в коллекции */ + begin + RARGS(NINDEX) := RARG; + exception + when others then + P_EXCEPTION(0, 'Изменяемый аргумент отсутствует в коллекции.'); + end; + end TARGS_EDIT; + + /* Удаление аргумента из коллекции */ + procedure TARGS_REMOVE + ( + RARGS in out nocopy TARGS, -- Изменяемая коллекция + SNAME in varchar2 -- Имя удаляемого аргумента + ) + is + NIND PKG_STD.TNUMBER; -- Индекс аргумента коллекции + begin + /* Найдем индекс аргумента в коллекции */ + NIND := TARGS_INDEX_BY_NAME(RARGS => RARGS, SNAME => SNAME); + /* Удалим его, если нашли */ + if (NIND is not null) then + RARGS.DELETE(NIND); + end if; + end TARGS_REMOVE; + + /* Сериализация коллекции аргументов */ + procedure TARGS_TO_XML + ( + RARGS in TARGS -- Коллекция аргументов + ) + is + begin + /* Открываем описание аргументов */ + PKG_XFAST.DOWN_NODE(SNAME => STAG_ARGS); + /* Обходим аргументы из коллекции */ + if ((RARGS is not null) and (RARGS.COUNT > 0)) then + for I in RARGS.FIRST .. RARGS.LAST + loop + begin + /* Добавляем описание аргумента */ + TARG_TO_XML(RARG => RARGS(I)); + exception + when NO_DATA_FOUND then + null; + end; + end loop; + end if; + /* Закрываем описание аргумента */ + PKG_XFAST.UP(); + end TARGS_TO_XML; + + /* Десериализация коллекции аргументов */ + function TARGS_FROM_XML + ( + CXML in clob -- XML-описание коллекции аргументов + ) return TARGS -- Коллекция аргументов + is + RRES TARGS; -- Буфер для результата + XDOC PKG_XPATH.TDOCUMENT; -- Документ XML + XROOT PKG_XPATH.TNODE; -- Корень документа XML + XNODE PKG_XPATH.TNODE; -- Буфер узла документа + XNODES PKG_XPATH.TNODES; -- Буфер коллекции узлов документа + begin + /* Инициализируем результат */ + RRES := TARGS(); + /* Если данные есть */ + if (CXML is not null) then + begin + /* Разбираем XML */ + XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); + /* Считываем корневой узел */ + XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); + /* Считывание списка аргументов */ + XNODES := PKG_XPATH.LIST_NODES(RPARENT_NODE => XROOT, SPATTERN => '/' || STAG_ARGS || '/' || STAG_ARG); + /* Цикл по списку аргументов */ + for I in 1 .. PKG_XPATH.COUNT_NODES(RNODES => XNODES) + loop + /* Считаем элемент по его номеру */ + XNODE := PKG_XPATH.ITEM_NODE(RNODES => XNODES, INUMBER => I); + /* Сериализуем и добавим его в коллекцию */ + RRES.EXTEND(); + RRES(RRES.LAST) := TARG_FROM_XML(CXML => PKG_XPATH.SERIALIZE_TO_CLOB(RNODE => XNODE)); + end loop; + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + exception + when others then + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + /* Вернем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end; + end if; + /* Вернём результат */ + return RRES; + end TARGS_FROM_XML; + + /* Сериализация настройки */ + procedure TOPT_TO_XML + ( + ROPT in TOPT -- Настройка + ) + is + begin + /* Открываем описание настройки */ + PKG_XFAST.DOWN_NODE(SNAME => STAG_OPT); + /* Аргументы */ + TARGS_TO_XML(RARGS => ROPT.RARGS); + /* Условия отбора */ + PKG_XFAST.HERB(SNAME => STAG_COND, SVALUE => ROPT.SCOND); + /* Закрываем описание настройки */ + PKG_XFAST.UP(); + end TOPT_TO_XML; + + /* Десериализация настройки */ + function TOPT_FROM_XML + ( + CXML in clob -- XML-описание настройки + ) return TOPT -- Настройка + is + RRES TOPT; -- Буфер для результата + XDOC PKG_XPATH.TDOCUMENT; -- Документ XML + XROOT PKG_XPATH.TNODE; -- Корень документа XML + XNODE PKG_XPATH.TNODE; -- Буфер узла документа + begin + /* Инициализируем настройку */ + RRES.RARGS := TARGS(); + /* Если данные есть */ + if (CXML is not null) then + begin + /* Разбираем XML */ + XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); + /* Считываем корневой узел */ + XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); + /* Считаваем узел настройки */ + XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => '/' || STAG_OPT); + /* Получаем значения */ + RRES.SCOND := PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => STAG_COND); + RRES.RARGS := TARGS_FROM_XML(CXML => PKG_XPATH.SERIALIZE_TO_CLOB(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XNODE, + SPATTERN => STAG_ARGS))); + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + exception + when others then + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + /* Вернем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end; + end if; + /* Вернём результат */ + return RRES; + end TOPT_FROM_XML; + /* Формирование идентификатора атрибута сущности */ function TATTR_ID_MAKE ( @@ -443,6 +862,9 @@ create or replace package body PKG_P8PANELS_QE_BASE as BINIT boolean := false; -- Признак инициализации атрибутов сущности begin /* Проверим корректность типа сущности */ + if (RENT.STYPE is null) then + P_EXCEPTION(0, 'Не указан тип сущности.'); + end if; if (RENT.STYPE not in (SENT_TYPE_TABLE, SENT_TYPE_VIEW)) then P_EXCEPTION(0, 'Сущности типа "%s" не поддерживаются.', @@ -635,6 +1057,9 @@ create or replace package body PKG_P8PANELS_QE_BASE as RVIEW PKG_OBJECT_DESC.TVIEW; -- Описание представления begin /* Проверим корректность типа сущности */ + if (STYPE is null) then + P_EXCEPTION(0, 'Не указан тип сущности.'); + end if; if (STYPE not in (SENT_TYPE_TABLE, SENT_TYPE_VIEW)) then P_EXCEPTION(0, 'Сущности типа "%s" не поддерживаются.', @@ -775,7 +1200,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as end TENTS_NEXT_NUMB; /* Добавление сущности в коллекцию */ - procedure TENTS_APPEND + procedure TENTS_ADD ( RENTS in out nocopy TENTS, -- Изменяемая коллекция SNAME in varchar2, -- Имя @@ -793,7 +1218,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as /* Добавляем её в коллекцию */ RENTS.EXTEND(); RENTS(RENTS.LAST) := RENT; - end TENTS_APPEND; + end TENTS_ADD; /* Удаление сущности из коллекции */ procedure TENTS_REMOVE @@ -804,7 +1229,9 @@ create or replace package body PKG_P8PANELS_QE_BASE as is NIND PKG_STD.TNUMBER; -- Индекс сущности в коллекции begin + /* Найдем индекс сущности в коллекции */ NIND := TENTS_INDEX_BY_ID(RENTS => RENTS, SID => SID); + /* Удалим её, если нашли */ if (NIND is not null) then RENTS.DELETE(NIND); end if; @@ -1055,7 +1482,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as end TRLS_LIST_BY_ST; /* Добавление связи в коллекцию */ - procedure TRLS_APPEND + procedure TRLS_ADD ( RRLS in out nocopy TRLS, -- Изменяемая коллекция SSOURCE in varchar2, -- Источник @@ -1073,7 +1500,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as /* Добавляем её в коллекцию */ RRLS.EXTEND(); RRLS(RRLS.LAST) := RRL; - end TRLS_APPEND; + end TRLS_ADD; /* Удаление связи из коллекции */ procedure TRLS_REMOVE @@ -1084,7 +1511,9 @@ create or replace package body PKG_P8PANELS_QE_BASE as is NIND PKG_STD.TNUMBER; -- Индекс связи в коллекции begin + /* Найдем индекс связи в коллекции */ NIND := TRLS_INDEX_BY_ID(RRLS => RRLS, SID => SID); + /* Удалим её, если нашли */ if (NIND is not null) then RRLS.DELETE(NIND); end if; @@ -1302,65 +1731,6 @@ create or replace package body PKG_P8PANELS_QE_BASE as end if; end QUERY_CH_DATE_SYNC; - /* Добавление запроса */ - procedure QUERY_INSERT - ( - SCODE in varchar2, -- Мнемокод - SNAME in varchar2, -- Наименование - NRN out number -- Рег. номер добавленного запроса - ) - is - begin - /* Проверим параметры */ - QUERY_CHECK(SCODE => SCODE, SNAME => SNAME); - /* Формируем рег. номер */ - NRN := GEN_ID(); - /* Добавляем данные */ - insert into P8PNL_QE_QUERY - (RN, CODE, name, AUTHOR, CH_DATE, READY, PBL) - values - (NRN, SCODE, SNAME, UTILIZER(), sysdate, 0, 0); - end QUERY_INSERT; - - /* Исправление запроса */ - procedure QUERY_UPDATE - ( - NRN in number, -- Рег. номер запроса - SCODE in varchar2, -- Мнемокод - SNAME in varchar2 -- Наименование - ) - is - begin - /* Проверим параметры */ - QUERY_CHECK(SCODE => SCODE, SNAME => SNAME); - /* Изменяем данные */ - update P8PNL_QE_QUERY T - set T.CODE = SCODE, - T.NAME = SNAME - where T.RN = NRN; - /* Контроль изменения данных */ - if (sql%notfound) then - PKG_MSG.RECORD_NOT_FOUND(NDOCUMENT => NRN, SUNIT_TABLE => 'P8PNL_QE_QUERY'); - end if; - /* Обновим дату изменения запроса */ - QUERY_CH_DATE_SYNC(NRN => NRN); - end QUERY_UPDATE; - - /* Удаление запроса */ - procedure QUERY_DELETE - ( - NRN in number -- Рег. номер запроса - ) - is - begin - /* Удаляем запись */ - delete from P8PNL_QE_QUERY T where T.RN = NRN; - /* Контроль изменения данных */ - if (sql%notfound) then - PKG_MSG.RECORD_NOT_FOUND(NDOCUMENT => NRN, SUNIT_TABLE => 'P8PNL_QE_QUERY'); - end if; - end QUERY_DELETE; - /* Сериализация сущностей запроса */ function QUERY_ENTS_TO_XML ( @@ -1503,6 +1873,72 @@ create or replace package body PKG_P8PANELS_QE_BASE as return RRLS; end QUERY_RLS_FROM_XML; + /* Сериализация настройки запроса */ + function QUERY_OPT_TO_XML + ( + ROPT in TOPT -- Настройка + ) return clob -- XML-описание + is + CRES clob; -- Буфер для результата + begin + /* Начинаем формирование XML */ + PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_); + /* Формируем XML настройки */ + TOPT_TO_XML(ROPT => ROPT); + /* Сериализуем */ + CRES := PKG_XFAST.SERIALIZE_TO_CLOB(); + /* Завершаем формирование XML */ + PKG_XFAST.EPILOGUE(); + /* Возвращаем полученное */ + return CRES; + exception + when others then + /* Завершаем формирование XML */ + PKG_XFAST.EPILOGUE(); + /* Вернем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end QUERY_OPT_TO_XML; + + /* Десериализация настройки запроса */ + function QUERY_OPT_FROM_XML + ( + CXML in clob -- XML-описание настройки запроса + ) return TOPT -- Настройка + is + ROPT TOPT; -- Буфер для результата + XDOC PKG_XPATH.TDOCUMENT; -- Документ XML + XROOT PKG_XPATH.TNODE; -- Корень документа XML + XNODE PKG_XPATH.TNODE; -- Буфер узла документа + begin + /* Инициализируем результат */ + ROPT.RARGS := TARGS(); + /* Если данные есть */ + if (CXML is not null) then + begin + /* Разбираем XML */ + XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); + /* Считываем корневой узел */ + XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); + /* Считываем узел настройки */ + XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => '/' || STAG_OPT); + /* Десериализуем его */ + ROPT := TOPT_FROM_XML(CXML => PKG_XPATH.SERIALIZE_TO_CLOB(RNODE => XNODE)); + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + exception + when others then + /* Освободим документ */ + PKG_XPATH.FREE(RDOCUMENT => XDOC); + /* Вернем ошибку */ + PKG_STATE.DIAGNOSTICS_STACKED(); + P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); + end; + end if; + /* Вернём сформированное */ + return ROPT; + end QUERY_OPT_FROM_XML; + /* Сериализация запроса */ function QUERY_TO_XML ( @@ -1518,9 +1954,9 @@ create or replace package body PKG_P8PANELS_QE_BASE as PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_, BALINE => true, BINDENT => true); /* Открываем корень */ PKG_XFAST.DOWN_NODE(SNAME => STAG_DATA); - /* Параметры */ - if (RQ.OPTS is not null) then - null; + /* Настройка */ + if (RQ.OPT is not null) then + TOPT_TO_XML(ROPT => QUERY_OPT_FROM_XML(CXML => RQ.OPT)); end if; /* Сущности (можно использовать просто PKG_XFAST.VALUE_XML и сразу отдать готовый XML из RQ.ENTS, но это приводит к формированию некорректного документа с лишней ">" между группами) */ if (RQ.ENTS is not null) then @@ -1547,8 +1983,19 @@ create or replace package body PKG_P8PANELS_QE_BASE as P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end QUERY_TO_XML; + /* Формирование описания запроса */ + function QUERY + ( + NRN in number -- Рег. номер запроса + ) return clob -- XML-описание + is + begin + /* Сериализуем запрос */ + return QUERY_TO_XML(NRN => NRN); + end QUERY; + /* Формирование списка запросов */ - function QUERY_LIST_GET + function QUERY_LIST ( SUSER in varchar2 -- Имя пользователя ) return clob -- Список запросов @@ -1607,18 +2054,66 @@ create or replace package body PKG_P8PANELS_QE_BASE as /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); - end QUERY_LIST_GET; + end QUERY_LIST; - /* Получение описания запроса */ - function QUERY_DESC_GET + /* Добавление запроса */ + procedure QUERY_INSERT ( - NRN in number -- Рег. номер запроса - ) return clob -- XML-описание + SCODE in varchar2, -- Мнемокод + SNAME in varchar2, -- Наименование + NRN out number -- Рег. номер добавленного запроса + ) is begin - /* Сериализуем запрос */ - return QUERY_TO_XML(NRN => NRN); - end QUERY_DESC_GET; + /* Проверим параметры */ + QUERY_CHECK(SCODE => SCODE, SNAME => SNAME); + /* Формируем рег. номер */ + NRN := GEN_ID(); + /* Добавляем данные */ + insert into P8PNL_QE_QUERY + (RN, CODE, name, AUTHOR, CH_DATE, READY, PBL) + values + (NRN, SCODE, SNAME, UTILIZER(), sysdate, 0, 0); + end QUERY_INSERT; + + /* Исправление запроса */ + procedure QUERY_UPDATE + ( + NRN in number, -- Рег. номер запроса + SCODE in varchar2, -- Мнемокод + SNAME in varchar2 -- Наименование + ) + is + begin + /* Проверим параметры */ + QUERY_CHECK(SCODE => SCODE, SNAME => SNAME); + /* Изменяем данные */ + update P8PNL_QE_QUERY T + set T.CODE = SCODE, + T.NAME = SNAME + where T.RN = NRN; + /* Контроль изменения данных */ + if (sql%notfound) then + PKG_MSG.RECORD_NOT_FOUND(NDOCUMENT => NRN, SUNIT_TABLE => 'P8PNL_QE_QUERY'); + end if; + /* Обновим дату изменения запроса */ + QUERY_CH_DATE_SYNC(NRN => NRN); + end QUERY_UPDATE; + + /* Удаление запроса */ + procedure QUERY_DELETE + ( + NRN in number -- Рег. номер запроса + ) + is + begin + /* Удаляем запись */ + delete from P8PNL_QE_QUERY T where T.RN = NRN; + /* Контроль изменения данных */ + if (sql%notfound) then + PKG_MSG.RECORD_NOT_FOUND(NDOCUMENT => NRN, SUNIT_TABLE => 'P8PNL_QE_QUERY'); + end if; + end QUERY_DELETE; /* Чтение сущностей запроса */ function QUERY_ENTS_GET @@ -1786,6 +2281,38 @@ create or replace package body PKG_P8PANELS_QE_BASE as /* Обновим дату изменения запроса */ QUERY_CH_DATE_SYNC(NRN => NRN); end QUERY_PBL_SET; + + /* Чтение настройки запроса */ + function QUERY_OPT_GET + ( + COPT in clob -- Сериализованное описание настройки запроса + ) return TOPT -- Настройка запроса + is + begin + /* Десериализуем */ + return QUERY_OPT_FROM_XML(CXML => COPT); + end QUERY_OPT_GET; + + /* Запись настройки запроса */ + procedure QUERY_OPT_SET + ( + NRN in number, -- Рег. номер запроса + ROPT in TOPT -- Настройка запроса + ) + is + COPT clob; -- Буфер для сериализации + begin + /* Сериализуем настройку */ + COPT := QUERY_OPT_TO_XML(ROPT => ROPT); + /* Сохраним её */ + update P8PNL_QE_QUERY T set T.OPT = COPT where T.RN = NRN; + /* Контроль изменения данных */ + if (sql%notfound) then + PKG_MSG.RECORD_NOT_FOUND(NDOCUMENT => NRN, SUNIT_TABLE => 'P8PNL_QE_QUERY'); + end if; + /* Обновим дату изменения запроса */ + QUERY_CH_DATE_SYNC(NRN => NRN); + end QUERY_OPT_SET; end PKG_P8PANELS_QE_BASE; /