P8-Panels/db/PKG_P8PANELS_BASE.pck

1032 lines
58 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

create or replace package PKG_P8PANELS_BASE as
/*Константы - Типовой постфикс тега для массива (при переводе XML -> JSON) */
SXML_ALWAYS_ARRAY_POSTFIX constant PKG_STD.TSTRING := '__SYSTEM__ARRAY__';
/* Константы - признаки наличия доступа */
NACCESS_YES constant number(1) := 1; -- Доступ есть
NACCESS_NO constant number(1) := 0; -- Доступа нет
/* Конвертация строки в число */
function UTL_S2N
(
SVALUE in varchar2 -- Конвертируемое строковое значение
) return number; -- Конвертированное число
/* Конвертация даты в число */
function UTL_S2D
(
SVALUE in varchar2 -- Конвертируемое строковое значение
) return date; -- Конвертированная дата
/* Проверка доступности документа */
function UTL_DOC_ACCESS_CHECK
(
NCOMPANY in number, -- Рег. номер организации
SUNIT_CODE in varchar2, -- Код раздела
NDOCUMENT in number -- Рег. номер документа
) return number; -- Флаг доступности (см. константы NACCESS_*)
/* Подготовка пользовательской строки поиска для вставки в запрос */
procedure UTL_SEARCH_PREPARE
(
SSEARCH in varchar2, -- Пользовательская строка поиска
SSEARCH_PREPARED out varchar2 -- Подготовленная строка поиска
);
/* Базовое исполнение действий */
procedure PROCESS
(
CIN in clob, -- Входные параметры
COUT out clob -- Результат
);
/* Базовая инициализация буфера отмеченных записей для панели */
procedure SELECTLIST_INIT
(
NIDENT in number -- Идентификатор буфера отмеченных записей
);
/* Базовая очистка буфера отмеченных записей для панели */
procedure SELECTLIST_CLEAR
(
NIDENT in number -- Идентификатор буфера отмеченных записей
);
end PKG_P8PANELS_BASE;
/
create or replace package body PKG_P8PANELS_BASE as
/* Константы - коды дествий запросов */
SRQ_ACTION_EXEC_STORED constant PKG_STD.TSTRING := 'EXEC_STORED'; -- Запрос на исполнение хранимой процедуры
/* Константы - тэги запросов */
SRQ_TAG_XREQUEST constant PKG_STD.TSTRING := 'XREQUEST'; -- Корневой тэг запроса
SRQ_TAG_XPAYLOAD constant PKG_STD.TSTRING := 'XPAYLOAD'; -- Тэг для данных запроса
SRQ_TAG_SACTION constant PKG_STD.TSTRING := 'SACTION'; -- Тэг для действия запроса
SRQ_TAG_SSTORED constant PKG_STD.TSTRING := 'SSTORED'; -- Тэг для имени хранимого объекта в запросе
SRQ_TAG_SRESP_ARG constant PKG_STD.TSTRING := 'SRESP_ARG'; -- Тэг для имени аргумента, формирующего данные ответа
SRQ_TAG_XARGUMENTS constant PKG_STD.TSTRING := 'XARGUMENTS'; -- Тэг для списка аргументов хранимого объекта/выборки в запросе
SRQ_TAG_XARGUMENT constant PKG_STD.TSTRING := 'XARGUMENT'; -- Тэг для аргумента хранимого объекта/выборки в запросе
SRQ_TAG_SNAME constant PKG_STD.TSTRING := 'SNAME'; -- Тэг для наименования в запросе
SRQ_TAG_SDATA_TYPE constant PKG_STD.TSTRING := 'SDATA_TYPE'; -- Тэг для типа данных в запросе
SRQ_TAG_VALUE constant PKG_STD.TSTRING := 'VALUE'; -- Тэг для значения в запросе
/* Константы - тэги ответов */
SRESP_TAG_XPAYLOAD constant PKG_STD.TSTRING := 'XPAYLOAD'; -- Тэг для данных ответа
SRESP_TAG_XOUT_ARGUMENTS constant PKG_STD.TSTRING := 'XOUT_ARGUMENTS'; -- Тэг для выходных аргументов хранимого объекта в ответе
SRESP_TAG_SDATA_TYPE constant PKG_STD.TSTRING := 'SDATA_TYPE'; -- Тэг для типа данных в ответе
SRESP_TAG_VALUE constant PKG_STD.TSTRING := 'VALUE'; -- Тэг для значения в ответе
SRESP_TAG_SNAME constant PKG_STD.TSTRING := 'SNAME'; -- Тэг для наименования в ответе
/* Константы - типы данных */
SDATA_TYPE_STR constant PKG_STD.TSTRING := 'STR'; -- Тип данных "строка"
SDATA_TYPE_NUMB constant PKG_STD.TSTRING := 'NUMB'; -- Тип данных "число"
SDATA_TYPE_DATE constant PKG_STD.TSTRING := 'DATE'; -- Тип данных "дата"
SDATA_TYPE_CLOB constant PKG_STD.TSTRING := 'CLOB'; -- Тип данных "текст"
/* Константы - состояния объектов БД */
SDB_OBJECT_STATE_VALID constant PKG_STD.TSTRING := 'VALID'; -- Объект валиден
/* Типы данных - аргументы */
type TARGUMENT is record
(
SNAME PKG_STD.TSTRING, -- Наименование
SDATA_TYPE PKG_STD.TSTRING, -- Тип данных (см. константы SPWS_DATA_TYPE_*)
SVALUE PKG_STD.TSTRING, -- Значение (строка)
NVALUE PKG_STD.TLNUMBER, -- Значение (число)
DVALUE PKG_STD.TLDATE, -- Значение (дата)
CVALUE clob -- Значение (текст)
);
/* Типы данных - коллекция аргументов запроса */
type TARGUMENTS is table of TARGUMENT;
/* Конвертация строки в число */
function UTL_S2N
(
SVALUE in varchar2 -- Конвертируемое строковое значение
) return number -- Конвертированное число
is
NVALUE PKG_STD.TNUMBER; -- Результат работы
begin
/* Пробуем конвертировать */
NVALUE := TO_NUMBER(replace(SVALUE, ',', '.'));
/* Отдаём результат */
return NVALUE;
exception
when others then
P_EXCEPTION(0, 'Неверный формат числа (%s).', SVALUE);
end UTL_S2N;
/* Конвертация даты в число */
function UTL_S2D
(
SVALUE in varchar2 -- Конвертируемое строковое значение
) return date -- Конвертированная дата
is
DVALUE PKG_STD.TLDATE; -- Результат работы
begin
/* Пробуем конвертировать */
begin
DVALUE := TO_DATE(SVALUE, 'YYYY-MM-DD');
exception
when others then
begin
DVALUE := TO_DATE(SVALUE, 'YYYY/MM/DD');
exception
when others then
begin
DVALUE := TO_DATE(SVALUE, 'DD.MM.YYYY');
exception
when others then
DVALUE := TO_DATE(SVALUE, 'DD/MM/YYYY');
end;
end;
end;
/* Отдаём результат */
return DVALUE;
exception
when others then
P_EXCEPTION(0, 'Неверный формат даты (%s).', SVALUE);
end UTL_S2D;
/* Проверка доступности документа */
function UTL_DOC_ACCESS_CHECK
(
NCOMPANY in number, -- Рег. номер организации
SUNIT_CODE in varchar2, -- Код раздела
NDOCUMENT in number -- Рег. номер документа
) return number -- Флаг доступности (см. константы NACCESS_*)
is
NRES PKG_STD.TNUMBER; -- Буфер для результата
NVERSION PKG_STD.TREF; -- Рег. номер версии
NCATALOG PKG_STD.TREF; -- Рег. номер каталога
NJUR_PERS PKG_STD.TREF; -- Рег. номер юридической принадлежности
NHIERARCHY PKG_STD.TREF; -- Рег. номер ирерархии
BTMP boolean; -- Буфер для расчетов
NTMP PKG_STD.TNUMBER; -- Буфер для расчетов
begin
/* Считаем стандартную атрибутику */
PKG_DOCUMENT.GET_ATTRS(NFLAG_SMART => 0,
SUNITCODE => SUNIT_CODE,
NDOCUMENT => NDOCUMENT,
BFOUND => BTMP,
NCOMPANY => NTMP,
NVERSION => NVERSION,
NCATALOG => NCATALOG,
NJUR_PERS => NJUR_PERS,
NHIERARCHY => NHIERARCHY);
/* Проверким доступ */
PKG_ENV.SMART_ACCESS(NCOMPANY => NCOMPANY,
NVERSION => NVERSION,
NCATALOG => NCATALOG,
NJUR_PERS => NJUR_PERS,
NHIERARCHY => NHIERARCHY,
SUNIT => SUNIT_CODE,
SACTION => null,
NRESULT => NRES);
/* Вернём результат */
if (NRES = 1) then
return NACCESS_YES;
else
return NACCESS_NO;
end if;
exception
/* В случае ошибки - доступ закрыт */
when others then
return NACCESS_NO;
end UTL_DOC_ACCESS_CHECK;
/* Подготовка пользовательской строки поиска для вставки в запрос */
procedure UTL_SEARCH_PREPARE
(
SSEARCH in varchar2, -- Пользовательская строка поиска
SSEARCH_PREPARED out varchar2 -- Подготовленная строка поиска
)
is
/* Локальные константы */
SANY_SYS constant char(1) := '%'; -- Маска "любое количество любых символов" Oracle
SONE_SYS constant char(1) := '_'; -- Маска "любой один символ" Oracle
SENT_WRD_DELIM constant varchar2(1) := ' '; -- Разделитель слов в предложении
SANY_PRS constant varchar2(240) := PKG_OPTIONS.STARSYMB; -- Маска "любое количество любых символов" Парус
SONE_PRS constant varchar2(240) := PKG_OPTIONS.QUESTSYMB; -- Маска "любой один символ" Парус
begin
/* Если пользовательская строка пустая - то это всё что угодно */
if (SSEARCH is null)
then
SSEARCH_PREPARED := SANY_SYS;
else
/* Подменим пользовательские маски на системные и соберем подготовленную строку поиска */
SSEARCH_PREPARED := '%' || replace(replace(replace(SSEARCH
,SANY_PRS
,SANY_SYS)
,SONE_PRS
,SONE_SYS)
,SENT_WRD_DELIM
,SANY_SYS) || '%';
end if;
end UTL_SEARCH_PREPARE;
/* Формирование сообщения об отсутствии значения */
function MSG_NO_DATA_MAKE
(
SPATH in varchar2 := null, -- Путь по которому ожидалось значение
SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке
) return varchar2 -- Сформированное сообщение об ошибке
is
SPATH_ PKG_STD.TSTRING; -- Буфер для пути
SMESSAGE_OBJECT_ PKG_STD.TSTRING; -- Буфер для наименования объекта
begin
/* Подготовим путь к выдаче */
if (SPATH is not null) then
SPATH_ := ' (' || SPATH || ')';
end if;
/* Подготовим наименование объекта к выдаче */
if (SMESSAGE_OBJECT is not null) then
SMESSAGE_OBJECT_ := ' элемента "' || SMESSAGE_OBJECT || '"';
else
SMESSAGE_OBJECT_ := ' элемента';
end if;
/* Вернём сформированное сообщение */
return 'Не указано значение' || SMESSAGE_OBJECT_ || SPATH_ || '.';
end MSG_NO_DATA_MAKE;
/* Конвертация стандартного типа данных (PKG_STD) в тип данных сервиса (PWS) */
function STD_DATA_TYPE_TO_STR
(
NSTD_DATA_TYPE in number -- Станартный тип данных
) return varchar2 -- Соответствующий тип данных сервиса
is
SRES PKG_STD.TSTRING; -- Буфер для результата
begin
/* Работаем от типа данных */
case NSTD_DATA_TYPE
/* Строка */
when PKG_STD.DATA_TYPE_STR then
SRES := SDATA_TYPE_STR;
/* Число */
when PKG_STD.DATA_TYPE_NUM then
SRES := SDATA_TYPE_NUMB;
/* Дата */
when PKG_STD.DATA_TYPE_DATE then
SRES := SDATA_TYPE_DATE;
/* Текст */
when PKG_STD.DATA_TYPE_CLOB then
SRES := SDATA_TYPE_CLOB;
/* Неизвестный тип данных */
else
P_EXCEPTION(0,
'Тип данных "%s" не поддерживается.',
COALESCE(TO_CHAR(NSTD_DATA_TYPE), '<НЕ ОПРЕДЕЛЁН>'));
end case;
/* Возвращаем результат */
return SRES;
end STD_DATA_TYPE_TO_STR;
/* Считывание значения ветки XML (строка) */
function NODE_SVAL_GET
(
XROOT in PKG_XPATH.TNODE, -- Корневая ветка для считывания значения
SPATH in varchar2, -- Путь для считывания данных
NREQUIRED in number := 0, -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке
) return varchar2 -- Считанное значение
is
XNODE PKG_XPATH.TNODE; -- Искомая ветка со значением (подходящая под шаблон)
SVAL PKG_STD.TSTRING; -- Результат работы
begin
/* Найдем нужную ветку по шаблону */
XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SPATH);
/* Если там нет ничего */
if (PKG_XPATH.IS_NULL(RNODE => XNODE)) then
/* Его и вернём */
SVAL := null;
else
/* Что-то есть - читаем данные */
begin
SVAL := PKG_XPATH.VALUE(RNODE => XNODE);
exception
when others then
P_EXCEPTION(0, 'Неверный формат строки (%s).', SPATH);
end;
end if;
/* Если значения нет, а оно должно быть - скажем об этом */
if ((SVAL is null) and (NREQUIRED = 1)) then
P_EXCEPTION(0, MSG_NO_DATA_MAKE(SPATH => SPATH, SMESSAGE_OBJECT => SMESSAGE_OBJECT));
end if;
/* Отдаём результат */
return SVAL;
end NODE_SVAL_GET;
/* Считывание значения ветки XML (число) */
function NODE_NVAL_GET
(
XROOT in PKG_XPATH.TNODE, -- Корневая ветка для считывания значения
SPATH in varchar2, -- Путь для считывания данных
NREQUIRED in number := 0, -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке
) return number -- Считанное значение
is
XNODE PKG_XPATH.TNODE; -- Искомая ветка со значением (подходящая под шаблон)
NVAL PKG_STD.TLNUMBER; -- Результат работы
begin
/* Найдем нужную ветку по шаблону */
XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SPATH);
/* Если там нет ничего */
if (PKG_XPATH.IS_NULL(RNODE => XNODE)) then
/* Его и вернём */
NVAL := null;
else
/* Что-то есть - читаем данные */
begin
NVAL := PKG_XPATH.VALUE_NUM(RNODE => XNODE);
exception
when others then
P_EXCEPTION(0, 'Неверный формат числа (%s).', SPATH);
end;
end if;
/* Если значения нет, а оно должно быть - скажем об этом */
if ((NVAL is null) and (NREQUIRED = 1)) then
P_EXCEPTION(0, MSG_NO_DATA_MAKE(SPATH => SPATH, SMESSAGE_OBJECT => SMESSAGE_OBJECT));
end if;
/* Отдаём результат */
return NVAL;
end NODE_NVAL_GET;
/* Считывание значения ветки XML (дата) */
function NODE_DVAL_GET
(
XROOT in PKG_XPATH.TNODE, -- Корневая ветка для считывания значения
SPATH in varchar2, -- Путь для считывания данных
NREQUIRED in number := 0, -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке
) return date -- Считанное значение
is
XNODE PKG_XPATH.TNODE; -- Искомая ветка со значением (подходящая под шаблон)
DVAL PKG_STD.TLDATE; -- Результат работы
begin
/* Найдем нужную ветку по шаблону */
XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SPATH);
/* Если там нет ничего */
if (PKG_XPATH.IS_NULL(RNODE => XNODE)) then
/* Его и вернём */
DVAL := null;
else
/* Что-то есть - читаем данные */
begin
DVAL := PKG_XPATH.VALUE_DATE(RNODE => XNODE);
exception
when others then
begin
DVAL := PKG_XPATH.VALUE_TS(RNODE => XNODE);
exception
when others then
begin
DVAL := PKG_XPATH.VALUE_TZ(RNODE => XNODE);
exception
when others then
P_EXCEPTION(0,
'Неверный формат даты (%s). Ожидалось: YYYY-MM-DD"T"HH24:MI:SS.FF3tzh:tzm, YYYY-MM-DD"T"HH24:MI:SS.FF3, YYYY-MM-DD"T"HH24:MI:SS, YYYY-MM-DD.',
SPATH);
end;
end;
end;
end if;
/* Если значения нет, а оно должно быть - скажем об этом */
if ((DVAL is null) and (NREQUIRED = 1)) then
P_EXCEPTION(0, MSG_NO_DATA_MAKE(SPATH => SPATH, SMESSAGE_OBJECT => SMESSAGE_OBJECT));
end if;
/* Отдаём результат */
return DVAL;
end NODE_DVAL_GET;
/* Считывание значения ветки XML (текст) */
function NODE_CVAL_GET
(
XROOT in PKG_XPATH.TNODE, -- Корневая ветка для считывания значения
SPATH in varchar2, -- Путь для считывания данных
NREQUIRED in number := 0, -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
SMESSAGE_OBJECT in varchar2 := null -- Наимемнование объекта для формулирования сообщения об ошибке
) return clob -- Считанное значение
is
XNODE PKG_XPATH.TNODE; -- Искомая ветка со значением (подходящая под шаблон)
CVAL clob; -- Результат работы
begin
/* Найдем нужную ветку по шаблону */
XNODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SPATH);
/* Если там нет ничего */
if (PKG_XPATH.IS_NULL(RNODE => XNODE)) then
/* Его и вернём */
CVAL := null;
else
/* Что-то есть - читаем данные */
begin
CVAL := PKG_XPATH.VALUE_CLOB(RNODE => XNODE);
exception
when others then
P_EXCEPTION(0, 'Неверный формат текстовых данных (%s).', SPATH);
end;
end if;
/* Если значения нет, а оно должно быть - скажем об этом */
if ((CVAL is null) and (NREQUIRED = 1)) then
P_EXCEPTION(0, MSG_NO_DATA_MAKE(SPATH => SPATH, SMESSAGE_OBJECT => SMESSAGE_OBJECT));
end if;
/* Отдаём результат */
return CVAL;
end NODE_CVAL_GET;
/* Считывание аргумента из коллекции */
function TARGUMENTS_GET
(
ARGUMENTS in TARGUMENTS, -- Коллекция аргументов
SARGUMENT in varchar2, -- Код аргумента
NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
) return TARGUMENT -- Найденный аргумент
is
begin
/* Если данные в коллекции есть */
if ((ARGUMENTS is not null) and (ARGUMENTS.COUNT > 0)) then
/* Обходим её */
for I in ARGUMENTS.FIRST .. ARGUMENTS.LAST
loop
/* Если встретился нужный аргумент */
if (ARGUMENTS(I).SNAME = SARGUMENT) then
/* Вернём его */
return ARGUMENTS(I);
end if;
end loop;
end if;
/* Если мы здесь - аргумент не нашелся, будем выдавать сообщение об ошибке если он был обязательным */
if (NREQUIRED = 1) then
P_EXCEPTION(0, 'Не задан обязательный аргумент "%s".', SARGUMENT);
else
/* Он не обязательный - вернём отсутствие данных */
return null;
end if;
end TARGUMENTS_GET;
/* Считывание значения аргумента из коллекции (строка) */
function TARGUMENTS_SVAL_GET
(
ARGUMENTS in TARGUMENTS, -- Коллекция аргументов
SARGUMENT in varchar2, -- Код аргумента
NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
) return varchar2 -- Значение аргумента
is
begin
/* Считаем и вернём значение */
return TARGUMENTS_GET(ARGUMENTS => ARGUMENTS, SARGUMENT => SARGUMENT, NREQUIRED => NREQUIRED).SVALUE;
end TARGUMENTS_SVAL_GET;
/* Считывание значения параметра из запроса (число) */
function TARGUMENTS_NVAL_GET
(
ARGUMENTS in TARGUMENTS, -- Коллекция аргументов
SARGUMENT in varchar2, -- Код аргумента
NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
) return number -- Значение аргумента
is
begin
/* Считаем и вернём значение */
return TARGUMENTS_GET(ARGUMENTS => ARGUMENTS, SARGUMENT => SARGUMENT, NREQUIRED => NREQUIRED).NVALUE;
end TARGUMENTS_NVAL_GET;
/* Считывание значения параметра из запроса (дата) */
function TARGUMENTS_DVAL_GET
(
ARGUMENTS in TARGUMENTS, -- Коллекция аргументов
SARGUMENT in varchar2, -- Код аргумента
NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
) return date -- Значение аргумента
is
begin
/* Считаем и вернём значение */
return TARGUMENTS_GET(ARGUMENTS => ARGUMENTS, SARGUMENT => SARGUMENT, NREQUIRED => NREQUIRED).DVALUE;
end TARGUMENTS_DVAL_GET;
/* Считывание значения параметра из запроса (текст) */
function TARGUMENTS_CVAL_GET
(
ARGUMENTS in TARGUMENTS, -- Коллекция аргументов
SARGUMENT in varchar2, -- Код аргумента
NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
) return clob -- Значение аргумента
is
begin
/* Считаем и вернём значение */
return TARGUMENTS_GET(ARGUMENTS => ARGUMENTS, SARGUMENT => SARGUMENT, NREQUIRED => NREQUIRED).CVALUE;
end TARGUMENTS_CVAL_GET;
/* Получение корневого элемента тела запроса */
function RQ_ROOT_GET
(
CRQ in clob -- Запрос
) return PKG_XPATH.TNODE -- Корневой элемент первой ветки тела документа
is
begin
/* Возвращаем корневой элемент документа */
return PKG_XPATH.ROOT_NODE(RDOCUMENT => PKG_XPATH.PARSE_FROM_CLOB(LCXML => CRQ));
end RQ_ROOT_GET;
/* Получение пути к запросу */
function RQ_PATH_GET
return varchar2 -- Путь к запросу
is
begin
return '/' || SRQ_TAG_XREQUEST;
end RQ_PATH_GET;
/* Получение пути к элементу действия запроса */
function RQ_ACTION_PATH_GET
return varchar2 -- Путь к элементу действия запроса
is
begin
return RQ_PATH_GET() || '/' || SRQ_TAG_SACTION;
end RQ_ACTION_PATH_GET;
/* Получение кода действия запроса */
function RQ_ACTION_GET
(
XRQ_ROOT in PKG_XPATH.TNODE := null, -- Корневая ветка запроса
NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
) return varchar2 -- Код действия запроса
is
begin
/* Вернем значение элемента тела с кодом действия */
return NODE_SVAL_GET(XROOT => XRQ_ROOT,
SPATH => RQ_ACTION_PATH_GET(),
NREQUIRED => NREQUIRED,
SMESSAGE_OBJECT => 'Код действия');
end RQ_ACTION_GET;
/* Получение пути к параметрам запроса */
function RQ_PAYLOAD_PATH_GET
return varchar2 -- Путь к параметрам запроса
is
begin
/* Вернем значение */
return RQ_PATH_GET() || '/' || SRQ_TAG_XPAYLOAD;
end RQ_PAYLOAD_PATH_GET;
/* Получение пути к элкменту параметров запроса */
function RQ_PAYLOAD_ITEM_PATH_GET
(
SITEM_TAG in varchar2 -- Тэг элемента
)
return varchar2 -- Путь к элементу параметров запроса
is
begin
/* Вернем значение */
return RQ_PAYLOAD_PATH_GET() || '/' || SITEM_TAG;
end RQ_PAYLOAD_ITEM_PATH_GET;
/* Считывание наименования исполняемого хранимого объекта из запроса */
function RQ_PAYLOAD_STORED_GET
(
XRQ_ROOT in PKG_XPATH.TNODE := null, -- Корневая ветка запроса
NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
) return varchar2 -- Наименование исполняемого хранимого объекта из запроса
is
begin
/* Вернем значение элемента тела с наименованием хранимого объекта */
return NODE_SVAL_GET(XROOT => XRQ_ROOT,
SPATH => RQ_PAYLOAD_ITEM_PATH_GET(SITEM_TAG => SRQ_TAG_SSTORED),
NREQUIRED => NREQUIRED,
SMESSAGE_OBJECT => 'Наименование процедуры/функции');
end RQ_PAYLOAD_STORED_GET;
/* Проверка исполняемого хранимого объекта из запроса */
procedure RQ_PAYLOAD_STORED_CHECK
(
XRQ_ROOT in PKG_XPATH.TNODE, -- Корневая ветка запроса
SSTORED in varchar2 := null -- Наименование проверяемого хранимого объекта (null - автоматическое считывание из запроса)
)
is
SSTORED_ PKG_STD.TSTRING; -- Буфер для наименования проверяемого хранимого объекта
RSTORED PKG_OBJECT_DESC.TSTORED; -- Описание хранимого объекта из БД
SPROCEDURE PKG_STD.TSTRING; -- Буфер для наименования хранимой процедуры
SPACKAGE PKG_STD.TSTRING; -- Буфер для наименования пакета, содержащего хранимый объект
RPACKAGE PKG_OBJECT_DESC.TPACKAGE; -- Описание пакета, содержащего хранимый объект
begin
/* Считаем наименование объекта из запроса или используем переданное в параметрах */
if (SSTORED is not null) then
SSTORED_ := SSTORED;
else
SSTORED_ := RQ_PAYLOAD_STORED_GET(XRQ_ROOT => XRQ_ROOT, NREQUIRED => 1);
end if;
/* Проверим, что это процедура или функция и она вообще существует */
if (PKG_OBJECT_DESC.EXISTS_STORED(SSTORED_NAME => SSTORED_) = 0) then
P_EXCEPTION(0,
'Хранимая процедура/функция "' || SSTORED_ || '" не определена.');
else
/* Проверим, что в имени нет ссылки на пакет */
PKG_EXS.UTL_STORED_PARSE_LINK(SSTORED => SSTORED_, SPROCEDURE => SPROCEDURE, SPACKAGE => SPACKAGE);
/* Если в имени есть ссылка на пакет - сначала проверим его состояние */
if (SPACKAGE is not null) then
RPACKAGE := PKG_OBJECT_DESC.DESC_PACKAGE(SPACKAGE_NAME => SPACKAGE, BRAISE_ERROR => false);
end if;
/* Если есть ссылка на пакет, или он не валиден - это ошибка */
if ((SPACKAGE is not null) and (RPACKAGE.STATUS <> SDB_OBJECT_STATE_VALID)) then
P_EXCEPTION(0,
'Пакет "' || SPACKAGE ||
'", содержащий хранимую процедуру/функцию, невалиден. Обращение к объекту невозможно.');
else
/* Нет ссылки на пакет или он валиден - проверяем глубже, получим описание объекта из БД */
RSTORED := PKG_OBJECT_DESC.DESC_STORED(SSTORED_NAME => SSTORED_, BRAISE_ERROR => false);
/* Проверим, что валидна */
if (RSTORED.STATUS <> SDB_OBJECT_STATE_VALID) then
P_EXCEPTION(0,
'Хранимая процедура/функция "' || SSTORED_ || '" невалидна. Обращение к объекту невозможно.');
else
/* Проверим, что это клиентский объект */
if (PKG_OBJECT_DESC.EXISTS_PRIV_EXECUTE(SSTORED_NAME => COALESCE(RSTORED.PACKAGE_NAME, SSTORED_)) = 0) then
P_EXCEPTION(0,
'Хранимая процедура/функция "' || SSTORED_ ||
'" не является клиентской. Обращение к объекту невозможно.');
end if;
end if;
end if;
end if;
end RQ_PAYLOAD_STORED_CHECK;
/* Считывание списка аргументов из запроса */
function RQ_PAYLOAD_ARGUMENTS_GET
(
XRQ_ROOT in PKG_XPATH.TNODE, -- Корневая ветка запроса
NREQUIRED in number := 0 -- Флаг выдачи сообщения об ошибке в случае отсутствия значения (0 - не выдавать, 1 - выдавать)
) return TARGUMENTS -- Коллекция аргументов из запроса
is
RES TARGUMENTS; -- Результат работы
SRQ_ARGUMENTS_PATH PKG_STD.TSTRING; -- Полный путь до аргументов выборки в запросе
XRQ_ARGUMENTS PKG_XPATH.TNODES; -- Коллекция элементов документа запроса с аргументами
XRQ_ARGUMENT PKG_XPATH.TNODE; -- Элемент документа запроса с аргументов
begin
/* Инициализируем результат */
RES := TARGUMENTS();
/* Сформируем полный путь до аргументов в выборке */
SRQ_ARGUMENTS_PATH := RQ_PAYLOAD_ITEM_PATH_GET(SITEM_TAG => SRQ_TAG_XARGUMENTS) || '/' || SRQ_TAG_XARGUMENT;
/* Считаем коллекцию аргументов из документа */
XRQ_ARGUMENTS := PKG_XPATH.LIST_NODES(RPARENT_NODE => XRQ_ROOT, SPATTERN => SRQ_ARGUMENTS_PATH);
/* Обходим коллекцию аргументов из документа */
for I in 1 .. PKG_XPATH.COUNT_NODES(RNODES => XRQ_ARGUMENTS)
loop
/* Берем очередной аргумент */
XRQ_ARGUMENT := PKG_XPATH.ITEM_NODE(RNODES => XRQ_ARGUMENTS, INUMBER => I);
/* Добавляем его в выходную коллекцию */
RES.EXTEND();
RES(RES.LAST).SNAME := NODE_SVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_SNAME);
RES(RES.LAST).SDATA_TYPE := NODE_SVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_SDATA_TYPE);
/* Проверим корректность данных - наименование */
if (RES(RES.LAST).SNAME is null) then
P_EXCEPTION(0,
'Для аргумента не задано наименование (%s).',
SRQ_ARGUMENTS_PATH || '/' || SRQ_TAG_SNAME);
end if;
/* Проверим корректность данных - тип данных */
if (RES(RES.LAST).SDATA_TYPE is null) then
P_EXCEPTION(0,
'Для аргумента "%s" не задан тип данных (%s).',
RES(RES.LAST).SNAME,
SRQ_ARGUMENTS_PATH || '/' || SRQ_TAG_SDATA_TYPE);
end if;
/* Считаем значение в зависимости от типа данных */
case
/* Строка */
when (RES(RES.LAST).SDATA_TYPE = SDATA_TYPE_STR) then
RES(RES.LAST).SVALUE := NODE_SVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_VALUE);
/* Число */
when (RES(RES.LAST).SDATA_TYPE = SDATA_TYPE_NUMB) then
RES(RES.LAST).NVALUE := NODE_NVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_VALUE);
/* Дата */
when (RES(RES.LAST).SDATA_TYPE = SDATA_TYPE_DATE) then
RES(RES.LAST).DVALUE := NODE_DVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_VALUE);
/* Текст */
when (RES(RES.LAST).SDATA_TYPE = SDATA_TYPE_CLOB) then
RES(RES.LAST).CVALUE := NODE_CVAL_GET(XROOT => XRQ_ARGUMENT, SPATH => SRQ_TAG_VALUE);
/* Неподдерживаемый тип данных */
else
P_EXCEPTION(0,
'Указанный для аргумента "%s" тип данных "%s" не поддерживается (%s).',
RES(RES.LAST).SNAME,
RES(RES.LAST).SDATA_TYPE,
SRQ_ARGUMENTS_PATH || '/' || SRQ_TAG_SDATA_TYPE);
end case;
end loop;
/* Проверка обязательности */
if ((RES.COUNT = 0) and (NREQUIRED = 1)) then
P_EXCEPTION(0, 'Не указаны аргументы (' || SRQ_ARGUMENTS_PATH || ').');
end if;
/* Возвращаем результат */
return RES;
end RQ_PAYLOAD_ARGUMENTS_GET;
/* Исполнение хранимой процедуры */
procedure EXEC_STORED
(
XRQ_ROOT in PKG_XPATH.TNODE, -- Корневой элемент тела документа запроса
COUT out clob -- Ответ на запрос
)
is
SRQ_STORED PKG_STD.TSTRING; -- Наименование исполняемого хранимого объекта из запроса
SRQ_RESP_ARG PKG_STD.TSTRING; -- Наименование выходного аргумента хранимого объекта из запроса для формирования тела ответа
RQ_ARGUMENTS TARGUMENTS; -- Коллекция аргументов хранимого объекта из запроса
ARGS PKG_OBJECT_DESC.TARGUMENTS; -- Коллекция формальных параметров хранимого объекта
RARG PKG_OBJECT_DESC.TARGUMENT; -- Формальный параметр хранимого объекта
ARGS_VALS PKG_CONTPRMLOC.TCONTAINER; -- Контейнер для фактических параметров хранимого объекта
RARG_VAL PKG_CONTAINER.TPARAM; -- Фактический параметр хранимого объекта
SARG_NAME PKG_STD.TSTRING; -- Наименование текущего обрабатываемого фактического параметра хранимого объекта
XRESP integer; -- Документ для ответа
XRESP_OUT_ARGUMENTS PKG_XMAKE.TNODE; -- Элемент для коллекции выходных параметров хранимого объекта
RRESP_ARGUMENT_VALUE PKG_XMAKE.TVALUE; -- Значение выходного параметра хранимого объекта
BRESP_ARG_FOUND boolean := false; -- Флаг присутствия в составе выходных аргументов аргумента с типом CLOB и именем, указанным в параметре запроса SRESP_ARG
begin
/* Создаём документ для ответа */
XRESP := PKG_XMAKE.OPEN_CURSOR();
/* Проверим хранимый объект в запросе */
RQ_PAYLOAD_STORED_CHECK(XRQ_ROOT => XRQ_ROOT);
/* Считываем наименование хранимого объекта из запроса */
SRQ_STORED := RQ_PAYLOAD_STORED_GET(XRQ_ROOT => XRQ_ROOT, NREQUIRED => 1);
/* Считываем наименование выходного аргумента хранимого объекта из запроса для формирования тела ответа */
SRQ_RESP_ARG := NODE_SVAL_GET(XROOT => XRQ_ROOT,
SPATH => RQ_PAYLOAD_ITEM_PATH_GET(SITEM_TAG => SRQ_TAG_SRESP_ARG),
NREQUIRED => 0,
SMESSAGE_OBJECT => 'Наименование выходного аргумента для формирования тела ответа');
/* Считаем список аргументов из запроса */
RQ_ARGUMENTS := RQ_PAYLOAD_ARGUMENTS_GET(XRQ_ROOT => XRQ_ROOT);
/* Считываем описание параметров хранимого объекта */
ARGS := PKG_OBJECT_DESC.DESC_ARGUMENTS(SSTORED_NAME => SRQ_STORED, BRAISE_ERROR => true);
/* Обходим входные параметры и формируем коллекцию значений */
for I in 1 .. PKG_OBJECT_DESC.COUNT_ARGUMENTS(RARGUMENTS => ARGS)
loop
/* Считываем очередной параметр */
RARG := PKG_OBJECT_DESC.FETCH_ARGUMENT(RARGUMENTS => ARGS, IINDEX => I);
/* Если это входной параметр */
if (RARG.IN_OUT in (PKG_STD.PARAM_TYPE_IN, PKG_STD.PARAM_TYPE_IN_OUT)) then
/* Добавим его значение в коллекцию фактических параметров */
case RARG.DATA_TYPE
/* Строка */
when PKG_STD.DATA_TYPE_STR then
PKG_CONTPRMLOC.APPENDS(RCONTAINER => ARGS_VALS,
SNAME => RARG.ARGUMENT_NAME,
SVALUE => TARGUMENTS_SVAL_GET(ARGUMENTS => RQ_ARGUMENTS,
SARGUMENT => RARG.ARGUMENT_NAME),
NIN_OUT => RARG.IN_OUT);
/* Число */
when PKG_STD.DATA_TYPE_NUM then
PKG_CONTPRMLOC.APPENDN(RCONTAINER => ARGS_VALS,
SNAME => RARG.ARGUMENT_NAME,
NVALUE => TARGUMENTS_NVAL_GET(ARGUMENTS => RQ_ARGUMENTS,
SARGUMENT => RARG.ARGUMENT_NAME),
NIN_OUT => RARG.IN_OUT);
/* Дата */
when PKG_STD.DATA_TYPE_DATE then
PKG_CONTPRMLOC.APPENDD(RCONTAINER => ARGS_VALS,
SNAME => RARG.ARGUMENT_NAME,
DVALUE => TARGUMENTS_DVAL_GET(ARGUMENTS => RQ_ARGUMENTS,
SARGUMENT => RARG.ARGUMENT_NAME),
NIN_OUT => RARG.IN_OUT);
/* Текст */
when PKG_STD.DATA_TYPE_CLOB then
PKG_CONTPRMLOC.APPENDLC(RCONTAINER => ARGS_VALS,
SNAME => RARG.ARGUMENT_NAME,
LCVALUE => TARGUMENTS_CVAL_GET(ARGUMENTS => RQ_ARGUMENTS,
SARGUMENT => RARG.ARGUMENT_NAME),
NIN_OUT => RARG.IN_OUT);
/* Неизвестный тип данных */
else
P_EXCEPTION(0,
'Тип данных (%s) входного параметра "%s" не поддерживается.',
RARG.DB_DATA_TYPE,
RARG.ARGUMENT_NAME);
end case;
end if;
end loop;
/* Исполняем процедуру */
PKG_SQL_CALL.EXECUTE_STORED(SSTORED_NAME => SRQ_STORED, RPARAM_CONTAINER => ARGS_VALS);
/* Обходим выходные параметры и собираем их в ответ */
SARG_NAME := PKG_CONTPRMLOC.FIRST_(RCONTAINER => ARGS_VALS);
while (SARG_NAME is not null)
loop
/* Считываем значение параметра */
RARG_VAL := PKG_CONTPRMLOC.GET(RCONTAINER => ARGS_VALS, SNAME => SARG_NAME);
/* Считываем описание параметра */
RARG := PKG_OBJECT_DESC.FETCH_ARGUMENT(RARGUMENTS => ARGS, SARGUMENT_NAME => SARG_NAME);
/* Если это выходной параметр */
if (RARG.IN_OUT in (PKG_STD.PARAM_TYPE_IN_OUT, PKG_STD.PARAM_TYPE_OUT)) then
/* Сформируем для него значение в зависимости от его типа */
case RARG.DATA_TYPE
/* Строка */
when PKG_STD.DATA_TYPE_STR then
RRESP_ARGUMENT_VALUE := PKG_XMAKE.VALUE(ICURSOR => XRESP,
SVALUE => PKG_CONTPRMLOC.GETS(RCONTAINER => ARGS_VALS,
SNAME => RARG_VAL.NAME));
/* Число */
when PKG_STD.DATA_TYPE_NUM then
RRESP_ARGUMENT_VALUE := PKG_XMAKE.VALUE(ICURSOR => XRESP,
NVALUE => PKG_CONTPRMLOC.GETN(RCONTAINER => ARGS_VALS,
SNAME => RARG_VAL.NAME));
/* Дата */
when PKG_STD.DATA_TYPE_DATE then
RRESP_ARGUMENT_VALUE := PKG_XMAKE.VALUE(ICURSOR => XRESP,
DVALUE => PKG_CONTPRMLOC.GETD(RCONTAINER => ARGS_VALS,
SNAME => RARG_VAL.NAME));
/* Текст */
when PKG_STD.DATA_TYPE_CLOB then
RRESP_ARGUMENT_VALUE := PKG_XMAKE.VALUE(ICURSOR => XRESP,
LCVALUE => PKG_CONTPRMLOC.GETLC(RCONTAINER => ARGS_VALS,
SNAME => RARG_VAL.NAME));
if ((SRQ_RESP_ARG is not null) and (RARG_VAL.NAME = SRQ_RESP_ARG)) then
COUT := PKG_CONTPRMLOC.GETLC(RCONTAINER => ARGS_VALS, SNAME => RARG_VAL.NAME);
BRESP_ARG_FOUND := true;
exit;
end if;
/* Неизвестный тип данных */
else
P_EXCEPTION(0,
'Тип данных (%s) выходного параметра "%s" не поддерживается.',
RARG.DB_DATA_TYPE,
RARG.ARGUMENT_NAME);
end case;
/* Добавим ветку выходного параметра в выходную коллекцию */
XRESP_OUT_ARGUMENTS := PKG_XMAKE.CONCAT(ICURSOR => XRESP,
RNODE00 => XRESP_OUT_ARGUMENTS,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => XRESP,
SNAME => SRESP_TAG_XOUT_ARGUMENTS,
RNODE00 => PKG_XMAKE.ELEMENT(ICURSOR => XRESP,
SNAME => SRESP_TAG_SNAME,
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XRESP,
SVALUE => RARG_VAL.NAME)),
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => XRESP,
SNAME => SRESP_TAG_VALUE,
RVALUE00 => RRESP_ARGUMENT_VALUE),
RNODE02 => PKG_XMAKE.ELEMENT(ICURSOR => XRESP,
SNAME => SRESP_TAG_SDATA_TYPE,
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XRESP,
SVALUE => STD_DATA_TYPE_TO_STR(NSTD_DATA_TYPE => RARG.DATA_TYPE)))));
end if;
/* Считываем наименование следующего параметра */
SARG_NAME := PKG_CONTPRMLOC.NEXT_(RCONTAINER => ARGS_VALS, SNAME => SARG_NAME);
end loop;
/* Проверим, что был найден опциональный аргумент для формирования полного ответа */
if ((SRQ_RESP_ARG is not null) and (not BRESP_ARG_FOUND)) then
P_EXCEPTION(0,
'В составе выходных параметров "%s" отсуствует аргумент "%s" типа "CLOB".',
SRQ_STORED,
SRQ_RESP_ARG);
end if;
/* Собираем ответ (только если не формировали полный ответ через аргумент для формирования полного ответа) */
if (not BRESP_ARG_FOUND) then
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => XRESP,
ITYPE => PKG_XMAKE.CONTENT_,
RNODE => PKG_XMAKE.ELEMENT(ICURSOR => XRESP,
SNAME => SRESP_TAG_XPAYLOAD,
RNODE00 => XRESP_OUT_ARGUMENTS));
end if;
/* Очистим контейнер параметров */
PKG_CONTPRMLOC.PURGE(RCONTAINER => ARGS_VALS);
/* Освобождаем документ результата */
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => XRESP);
exception
when others then
/* Закроем курсор и вернем ошибку */
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => XRESP);
/* Покажем ошибку */
PKG_STATE.DIAGNOSTICS_STACKED();
P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
end EXEC_STORED;
/* Базовое исполнение действий */
procedure PROCESS
(
CIN in clob, -- Входные параметры
COUT out clob -- Результат
)
is
XRQ_ROOT PKG_XPATH.TNODE; -- Корневой элемент тела документа запроса
SRQ_ACTION PKG_STD.TSTRING; -- Код действия из запроса
begin
/* Разбираем запрос */
XRQ_ROOT := RQ_ROOT_GET(CRQ => CIN);
/* Считываем код действия из запроса */
SRQ_ACTION := RQ_ACTION_GET(XRQ_ROOT => XRQ_ROOT, NREQUIRED => 1);
/* Вызываем обработчик в зависимости от кода действия */
case SRQ_ACTION
/* Исполнение хранимой процедуры */
when SRQ_ACTION_EXEC_STORED then
EXEC_STORED(XRQ_ROOT => XRQ_ROOT, COUT => COUT);
/* Неизвестное действие */
else
P_EXCEPTION(0, 'Действие "%s" не поддерживается.', SRQ_ACTION);
end case;
end PROCESS;
/* Базовое добавление в буфер отмеченных записей для панели */
procedure SELECTLIST_INSERT
(
NIDENT in number, -- Идентификатор процесса
SAUTHID in varchar2, -- Пользователь
SSESSION_ID in varchar2, -- Идентификатор сеанса
SCONNECT_EXT in varchar2, -- Внешний идентификатор сеанса
NCOMPANY in number := null, -- Организация
NDOCUMENT in number, -- Документ
SUNITCODE in varchar2 := null, -- Код раздела документа
SACTIONCODE in varchar2 := null, -- Код действия документа
NCRN in number := null, -- Каталог документа
NDOCUMENT1 in number := null, -- Документ 1
SUNITCODE1 in varchar2 := null, -- Код раздела документа 1
SACTIONCODE1 in varchar2 := null, -- Код действия документа 1
NRN out number -- Рег. номер добавленной записи
)
is
begin
/* Формируем рег. номер */
NRN := GEN_ID();
/* Добвляем запись */
insert into P8PNL_SELECTLIST
(RN,
IDENT,
authid,
SESSION_ID,
CONNECT_EXT,
COMPANY,
DOCUMENT,
UNITCODE,
ACTIONCODE,
CRN,
DOCUMENT1,
UNITCODE1,
ACTIONCODE1)
values
(NRN,
NIDENT,
SAUTHID,
SSESSION_ID,
SCONNECT_EXT,
NCOMPANY,
NDOCUMENT,
SUNITCODE,
SACTIONCODE,
NCRN,
NDOCUMENT1,
SUNITCODE1,
SACTIONCODE1);
end SELECTLIST_INSERT;
/* Удаление записи буфера отмеченных записей для панели */
procedure SELECTLIST_DELETE
(
NRN in number -- Рег. номер удаляемой записи
)
is
begin
delete from P8PNL_SELECTLIST T where T.RN = NRN;
end SELECTLIST_DELETE;
/* Базовая инициализация буфера отмеченных записей для панели */
procedure SELECTLIST_INIT
(
NIDENT in number -- Идентификатор буфера отмеченных записей
)
is
NRN PKG_STD.TREF; -- Рег. номер добавленной записи буфера панелей
begin
/* Очищаем буфер панелей */
SELECTLIST_CLEAR(NIDENT => NIDENT);
/* Обходим системный буфер отмеченных записей */
for C in (select T.* from SELECTLIST T where T.IDENT = NIDENT)
loop
/* Копируем запись */
SELECTLIST_INSERT(NIDENT => C.IDENT,
SAUTHID => C.AUTHID,
SSESSION_ID => C.SESSION_ID,
SCONNECT_EXT => C.CONNECT_EXT,
NCOMPANY => C.COMPANY,
NDOCUMENT => C.DOCUMENT,
SUNITCODE => C.UNITCODE,
SACTIONCODE => C.ACTIONCODE,
NCRN => C.CRN,
NDOCUMENT1 => C.DOCUMENT1,
SUNITCODE1 => C.UNITCODE1,
SACTIONCODE1 => C.ACTIONCODE1,
NRN => NRN);
end loop;
end SELECTLIST_INIT;
/* Базовая очистка буфера отмеченных записей для панели */
procedure SELECTLIST_CLEAR
(
NIDENT in number -- Идентификатор буфера отмеченных записей
)
is
begin
/* Обходим буфер панелей */
for C in (select T.RN from P8PNL_SELECTLIST T where T.IDENT = NIDENT)
loop
SELECTLIST_DELETE(NRN => C.RN);
end loop;
end SELECTLIST_CLEAR;
end PKG_P8PANELS_BASE;
/