P8-ExchangeService/db/UDO_PKG_EXS_TEST.pck

770 lines
32 KiB
Plaintext
Raw 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 UDO_PKG_EXS_TEST as
/* Запросить контрагента */
procedure RECIVE_AGENT
(
NREMOTE_AGENT in number -- Рег. номер контрагента в удалённой БД
);
/* Обработка ответа с информацией о контрагенте от тестового стенда */
procedure PROCESS_AGN_INFO_RESP
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
);
/* Обработка запроса на создание сессии */
procedure RESP_LOGIN
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
);
/* Обработка запроса на поиск контрагента */
procedure RESP_FIND_AGENT
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
);
/* Обработка запроса на поиск договора */
procedure RESP_FIND_CONTRACT
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
);
/* Электронная инвентаризация - аутентификация */
procedure INV_CHECKAUTH_XML
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
);
/* Электронная инвентаризация - считывание пользователей */
procedure INV_GETUSERS_XML
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
);
end;
/
create or replace package body UDO_PKG_EXS_TEST as
/* Тип данных для коллекции шаблонов вспомогательных слов поиска */
type THELPER_PATTERNS is table of varchar2(4000);
/* Проверка на присутствие слова в списке вспомогательных */
function UTL_HELPER_CHECK
(
SWORD in varchar2, -- Проверяемое слово
HELPER_PATTERNS in THELPER_PATTERNS -- Коллекция шаблонов вспомогательных слов
)
return boolean -- Резульата проверки
is
BRES boolean; -- Буфер для результата
begin
/* Инициализируем буфер */
BRES := false;
/* Если коллекция не пуста */
if ((HELPER_PATTERNS is not null) and (HELPER_PATTERNS.COUNT > 0)) then
/* Обходим её */
for I in HELPER_PATTERNS.FIRST .. HELPER_PATTERNS.LAST
loop
/* Если слово есть в коллекции */
if (LOWER(SWORD) like LOWER(HELPER_PATTERNS(I))) then
/* Выставим флаг присутствия и завершим поиск */
BRES := true;
exit;
end if;
end loop;
end if;
/* Возвращаем ответ */
return BRES;
end UTL_HELPER_CHECK;
/* Инициализация общих вспомогательных поисковых фраз */
procedure UTL_HELPER_INIT_COMMON
(
HELPER_PATTERNS in out THELPER_PATTERNS -- Коллекция шаблонов вспомогательных слов
)
is
begin
/* Создадим пустую коллекцию если надо */
if (HELPER_PATTERNS is null) then
HELPER_PATTERNS := THELPER_PATTERNS();
end if;
/* Наполним её общими поисковыми вспомогательными фразами */
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'расскажи';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'про';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'о';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'об';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'по';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'сведения';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'информацию';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'информация';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'информации';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'инфы';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'инфу';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'дай';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'нарой';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'запроси';
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'найди';
end UTL_HELPER_INIT_COMMON;
/* Подготовка поисковой фразы к участию в выборке */
function UTL_SEARCH_STR_PREPARE
(
SSEARCH_STR in varchar2, -- Поисковая фраза
SDELIM in varchar2, -- Разделитель слов в поисковой фразе
HELPER_PATTERNS in THELPER_PATTERNS -- Коллекция шаблонов вспомогательных слов
)
return varchar2 -- Подготовленная поисковая фраза
is
SRES varchar2(32000); -- Результат работы
begin
/* Обходим слова поисковой фразы */
for W in (select REGEXP_SUBSTR(T.STR, '[^' || SDELIM || ']+', 1, level) SWRD
from (select replace(replace(SSEARCH_STR, ',', ''), '.', '') STR from DUAL) T
connect by INSTR(T.STR, SDELIM, 1, level - 1) > 0)
loop
/* Если слово не в списке вспомогательных */
if (not UTL_HELPER_CHECK(SWORD => W.SWRD, HELPER_PATTERNS => HELPER_PATTERNS)) then
/* Оставляем его в итоговой выборке */
SRES := SRES || '%' || W.SWRD;
end if;
end loop;
/* Уберем лишние пробелы и готовим для поиска */
SRES := '%' || trim(SRES) || '%';
/* Вернем ответ */
return SRES;
end UTL_SEARCH_STR_PREPARE;
/* Запросить контрагента */
procedure RECIVE_AGENT
(
NREMOTE_AGENT in number -- Рег. номер контрагента в удалённой БД
)
is
SEXSSERVICEFN EXSSERVICEFN.CODE%type; -- Мнемокод функции сервиса
NEXSSERVICEFN EXSSERVICEFN.RN%type; -- Рег. номер функции сервиса
RCTMP sys_refcursor; -- Буфер для измененной позиции очереди
begin
/* Инициализируем мнемокод функции сервиса */
SEXSSERVICEFN := 'ПолучениеКонтрагента';
/* Найдем рег. номер функции сервиса */
FIND_EXSSERVICEFN_CODE(NFLAG_SMART => 0, NFLAG_OPTION => 0, SCODE => SEXSSERVICEFN, NRN => NEXSSERVICEFN);
/* Поместим задание в очередь */
PKG_EXS.QUEUE_PUT(NEXSSERVICEFN => NEXSSERVICEFN,
BMSG => CLOB2BLOB(LCDATA => 'CPRMS={SACTION:"GET_AGENT",NAGENT:' || TO_CHAR(NREMOTE_AGENT) || '}'),
RCQUEUE => RCTMP);
end RECIVE_AGENT;
/* Обработка ответа с информацией о контрагенте от тестового стенда */
procedure PROCESS_AGN_INFO_RESP
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
)
is
REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди
CTMP clob; -- Буфер для конвертации
RCTMP sys_refcursor; -- Буфер для измененной позиции очереди
NCOMPANY PKG_STD.TREF; -- Рег. номер организации
NCRN PKG_STD.TREF; -- Рег. номер каталога
SAGNABBR AGNLIST.AGNABBR%type; -- Мнемокод контрагента
SAGNNAME AGNLIST.AGNNAME%type; -- Наименование контрагента
NAGENT AGNLIST.RN%type; -- Рег. номер добавленного контрагента
begin
/* Инициализируем организацию */
NCOMPANY := 136018;
/* Считаем запись очереди */
REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE);
/* Конвертируем в кодировку БД */
CTMP := BLOB2CLOB(LBDATA => REXSQUEUE.RESP, SCHARSET => 'UTF8');
/* Кладём конвертированное обратно (просто для удобства мониторинга) */
PKG_EXS.QUEUE_MSG_SET(NEXSQUEUE => REXSQUEUE.RN, BMSG => CLOB2BLOB(LCDATA => CTMP), RCQUEUE => RCTMP);
/* Разбираем ответ сервера */
if (CTMP is not null) then
select EXTRACTVALUE(XMLTYPE(CTMP), '/AGENT/SAGNABBR') SAGNABBR,
EXTRACTVALUE(XMLTYPE(CTMP), '/AGENT/SAGNNAME') SAGNNAME
into SAGNABBR,
SAGNNAME
from DUAL;
else
P_EXCEPTION(0, 'Не указаны данные для добавления контрагента.');
end if;
if (SAGNABBR is null) then
P_EXCEPTION(0, 'В ответе сервера не указан мнемокод контрагента.');
end if;
if (SAGNNAME is null) then
P_EXCEPTION(0,
'В ответе сервера не указано наименование контрагента.');
end if;
/* Найдём каталог */
FIND_ACATALOG_NAME(NFLAG_SMART => 0,
NCOMPANY => NCOMPANY,
NVERSION => null,
SUNITCODE => 'AGNLIST',
SNAME => 'ExchangeService',
NRN => NCRN);
/* Регистрируем контрагента */
P_AGNLIST_BASE_INSERT(NCOMPANY => NCOMPANY,
NCRN => NCRN,
SAGNABBR => SUBSTR(NIDENT || SAGNABBR, 1, 20),
SAGNNAME => SAGNNAME || ' ' || NIDENT,
NRN => NAGENT);
exception
when others then
PKG_EXS.PRC_RESP_ARG_STR_SET(NIDENT => NIDENT, SARG => PKG_EXS.SCONT_FLD_SERR, SVALUE => sqlerrm);
end PROCESS_AGN_INFO_RESP;
/* Обработка запроса на создание сессии */
procedure RESP_LOGIN
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
)
is
REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди
CTMP clob; -- Буфер для конвертации
RCTMP sys_refcursor; -- Буфер для измененной позиции очереди
SUSER PKG_STD.TSTRING; -- Имя пользователя
SPASS PKG_STD.TSTRING; -- Пароль пользователя
SCOMPANY PKG_STD.TSTRING; -- Наименование организации
SCONNECT PKG_STD.TSTRING; -- Идентификатор сесии
begin
/* Считаем запись очереди */
REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE);
/* Забираем данные сообщения и конвертируем в кодировку БД */
CTMP := BLOB2CLOB(LBDATA => REXSQUEUE.MSG, SCHARSET => 'UTF8');
/* Кладём конвертированное обратно (просто для удобства мониторинга) */
PKG_EXS.QUEUE_MSG_SET(NEXSQUEUE => REXSQUEUE.RN, BMSG => CLOB2BLOB(LCDATA => CTMP), RCQUEUE => RCTMP);
/* Извлекаем логин и пароль */
if (CTMP is not null) then
select EXTRACTVALUE(XMLTYPE(CTMP), '/auth/user') SUSER,
EXTRACTVALUE(XMLTYPE(CTMP), '/auth/pass') SPASS,
EXTRACTVALUE(XMLTYPE(CTMP), '/auth/company') SCOMP
into SUSER,
SPASS,
SCOMPANY
from DUAL;
else
P_EXCEPTION(0, 'Не указаны данные для аутентификации.');
end if;
/* Если и логин и пароль и организация есть */
if ((SUSER is not null) and (SPASS is not null) and (SCOMPANY is not null)) then
/* Формируем идентификатор сесии */
SCONNECT := SYS_GUID();
/* Создаём сессию */
PKG_SESSION.LOGON_WEB(SCONNECT => SCONNECT,
SUTILIZER => SUSER,
SPASSWORD => SPASS,
SIMPLEMENTATION => 'Other',
SAPPLICATION => 'Other',
SCOMPANY => SCOMPANY);
/* Выставляем результат обработки */
PKG_EXS.PRC_RESP_ARG_BLOB_SET(NIDENT => NIDENT,
SARG => PKG_EXS.SCONT_FLD_BRESP,
BVALUE => CLOB2BLOB(LCDATA => SCONNECT, SCHARSET => 'UTF8'));
else
P_EXCEPTION(0, 'Не указано имя пользователя, пароль или организация.');
end if;
exception
when others then
PKG_EXS.PRC_RESP_ARG_STR_SET(NIDENT => NIDENT, SARG => PKG_EXS.SCONT_FLD_SERR, SVALUE => sqlerrm);
end RESP_LOGIN;
/* Обработка запроса на поиск контрагента */
procedure RESP_FIND_AGENT
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
)
is
HELPER_PATTERNS THELPER_PATTERNS; -- Коллекция шаблонов вспомогательных слов поиска
REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди
CTMP clob; -- Буфер для конвертации
CRESP clob; -- Данные для ответа
RCTMP sys_refcursor; -- Буфер для измененной позиции очереди
begin
/* Считаем запись очереди */
REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE);
/* Инициализируем коллекцию слов-помошников */
UTL_HELPER_INIT_COMMON(HELPER_PATTERNS => HELPER_PATTERNS);
/* Наполняем её значениями индивидуальными для данного запроса */
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'контрагент%';
/* Забираем данные сообщения и конвертируем в кодировку БД */
CTMP := BLOB2CLOB(LBDATA => REXSQUEUE.MSG, SCHARSET => 'UTF8');
/* Кладём конвертированное обратно (просто для удобства мониторинга) */
PKG_EXS.QUEUE_MSG_SET(NEXSQUEUE => REXSQUEUE.RN, BMSG => CLOB2BLOB(LCDATA => CTMP), RCQUEUE => RCTMP);
/* Если есть что искать */
if (CTMP is not null) then
/* Подготовим поисковую фразу */
CTMP := UTL_SEARCH_STR_PREPARE(SSEARCH_STR => CTMP, SDELIM => ' ', HELPER_PATTERNS => HELPER_PATTERNS);
/* Инициализируем ответ */
CRESP := 'Контрагент не найден';
/* Ищем запрошенного контрагента */
for C in (select T.AGNNAME ||
DECODE(T.AGNTYPE, 1, ', физическое лицо', ', юридическое лицо') SAGENT,
(select count(CN.RN) from CONTRACTS CN where CN.AGENT = T.RN) NCNT_CONTRACTS,
(select sum(CN.DOC_SUM) from CONTRACTS CN where CN.AGENT = T.RN) NSUM_CONTRACTS
from AGNLIST T
where ((LOWER(T.AGNABBR) like LOWER(CTMP)) or (LOWER(T.AGNNAME) like LOWER(CTMP)))
and ROWNUM <= 1)
loop
CRESP := C.SAGENT;
if (C.NCNT_CONTRACTS = 0) then
CRESP := CRESP || ', не имеет зарегистрированных в системе договоров';
else
CRESP := CRESP || ', зарегистрировано договоров: ' || TO_CHAR(C.NCNT_CONTRACTS);
if (C.NSUM_CONTRACTS <> 0) then
CRESP := CRESP || ', на общую сумму: ' || TO_CHAR(C.NSUM_CONTRACTS) || ' руб.';
end if;
end if;
end loop;
else
CRESP := 'Не указан поисковый запрос';
end if;
/* Возвращаем ответ */
PKG_EXS.PRC_RESP_ARG_BLOB_SET(NIDENT => NIDENT,
SARG => PKG_EXS.SCONT_FLD_BRESP,
BVALUE => CLOB2BLOB(LCDATA => CRESP, SCHARSET => 'UTF8'));
end RESP_FIND_AGENT;
/* Обработка запроса на поиск договора */
procedure RESP_FIND_CONTRACT
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
)
is
HELPER_PATTERNS THELPER_PATTERNS; -- Коллекция шаблонов вспомогательных слов поиска
REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди
CTMP clob; -- Буфер для конвертации
CRESP clob; -- Данные для ответа
RCTMP sys_refcursor; -- Буфер для измененной позиции очереди
begin
/* Считаем запись очереди */
REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE);
/* Инициализируем коллекцию слов-помошников */
UTL_HELPER_INIT_COMMON(HELPER_PATTERNS => HELPER_PATTERNS);
/* Наполняем её значениями индивидуальными для данного запроса */
HELPER_PATTERNS.EXTEND();
HELPER_PATTERNS(HELPER_PATTERNS.LAST) := 'договор%';
/* Забираем данные сообщения и конвертируем в кодировку БД */
CTMP := BLOB2CLOB(LBDATA => REXSQUEUE.MSG, SCHARSET => 'UTF8');
/* Кладём конвертированное обратно (просто для удобства мониторинга) */
PKG_EXS.QUEUE_MSG_SET(NEXSQUEUE => REXSQUEUE.RN, BMSG => CLOB2BLOB(LCDATA => CTMP), RCQUEUE => RCTMP);
/* Если есть что искать */
if (CTMP is not null) then
/* Подготовим поисковую фразу */
CTMP := UTL_SEARCH_STR_PREPARE(SSEARCH_STR => CTMP, SDELIM => ' ', HELPER_PATTERNS => HELPER_PATTERNS);
/* Ищем запрошенный договор */
begin
select DECODE(T.INOUT_SIGN, 0, 'Входящий', 'Исходящий') || ' договор №' ||
NVL(T.EXT_NUMBER, trim(T.DOC_PREF) || '-' || trim(T.DOC_NUMB)) || ' от ' ||
TO_CHAR(T.DOC_DATE, 'dd.mm.yyyy') || ' с контрагентом ' || AG.AGNNAME || ' на сумму ' ||
TO_CHAR(T.DOC_SUM) || ' ' || CN.INTCODE || ', оплачено ' || TO_CHAR(T.FACT_OUTPAY_SUM) || ' ' ||
CN.INTCODE SDOC
into CRESP
from CONTRACTS T,
AGNLIST AG,
CURNAMES CN
where ((LOWER(T.EXT_NUMBER) like LOWER(CTMP)) or
(LOWER(trim(T.DOC_PREF) || trim(T.DOC_NUMB)) like LOWER(CTMP)))
and T.AGENT = AG.RN
and T.CURRENCY = CN.RN
and ROWNUM <= 1;
exception
when NO_DATA_FOUND then
CRESP := 'Договор не найден';
end;
else
CRESP := 'Не указан поисковый запрос';
end if;
/* Возвращаем ответ */
PKG_EXS.PRC_RESP_ARG_BLOB_SET(NIDENT => NIDENT,
SARG => PKG_EXS.SCONT_FLD_BRESP,
BVALUE => CLOB2BLOB(LCDATA => CRESP, SCHARSET => 'UTF8'));
end RESP_FIND_CONTRACT;
/* Электронная инвентаризация - аутентификация */
procedure INV_CHECKAUTH_XML
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
)
is
REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди
/**/
SREQDEVICEID varchar2(30);
XCHECKAUTHRESPONSE DBMS_XMLDOM.DOMNODE;
XRESULT DBMS_XMLDOM.DOMNODE;
XNODE DBMS_XMLDOM.DOMNODE;
CRESPONSE clob;
XDOC DBMS_XMLDOM.DOMDOCUMENT;
/**/
XMLPARCER DBMS_XMLPARSER.PARSER;
XENVELOPE DBMS_XMLDOM.DOMNODE;
XBODY DBMS_XMLDOM.DOMNODE;
XNODELIST DBMS_XMLDOM.DOMNODELIST;
XNODE_ROOT DBMS_XMLDOM.DOMNODE;
SNODE varchar2(100);
CREQ clob;
/**/
STSD constant varchar2(20) := 'tsd';
SCHECKAUTHRESPONSE constant varchar2(20) := 'CheckAuthResponse';
SDEVICEID constant varchar2(20) := 'DeviceID';
SRESULT constant varchar2(20) := 'Result';
SSOAPENV constant varchar2(20) := 'soapenv';
SENVELOPE constant varchar2(20) := 'Envelope';
SHEADER constant varchar2(20) := 'Header';
SBODY constant varchar2(20) := 'Body';
/* Создание ветки XML */
function CREATENODE
(
STAG in varchar2,
SNS in varchar2 default null,
SVAL in varchar2 default null
) return DBMS_XMLDOM.DOMNODE is
XEL DBMS_XMLDOM.DOMELEMENT;
XNODE DBMS_XMLDOM.DOMNODE;
XTEXT DBMS_XMLDOM.DOMNODE;
begin
if SNS is not null then
XEL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => STAG, NS => SNS);
XNODE := DBMS_XMLDOM.MAKENODE(XEL);
DBMS_XMLDOM.SETPREFIX(N => XNODE, PREFIX => SNS);
else
XEL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => STAG);
XNODE := DBMS_XMLDOM.MAKENODE(XEL);
end if;
if SVAL is not null then
XTEXT := DBMS_XMLDOM.APPENDCHILD(XNODE, DBMS_XMLDOM.MAKENODE(DBMS_XMLDOM.CREATETEXTNODE(XDOC, SVAL)));
end if;
return XNODE;
end;
/* Считывание значения ветки XML */
function GETNODEVAL
(
XROOTNODE in DBMS_XMLDOM.DOMNODE,
SPATTERN in varchar2
) return varchar2 is
XNODE DBMS_XMLDOM.DOMNODE;
SVAL varchar2(100);
begin
XNODE := DBMS_XSLPROCESSOR.SELECTSINGLENODE(N => XROOTNODE, PATTERN => SPATTERN);
if DBMS_XMLDOM.ISNULL(XNODE) then
return null;
end if;
SVAL := DBMS_XMLDOM.GETNODEVALUE(DBMS_XMLDOM.GETFIRSTCHILD(N => XNODE));
return SVAL;
end GETNODEVAL;
/* Создание документа для ответа */
procedure CREATERESPONSEDOC is
begin
XDOC := DBMS_XMLDOM.NEWDOMDOCUMENT;
DBMS_XMLDOM.SETVERSION(XDOC
,'1.0" encoding="UTF-8');
DBMS_XMLDOM.SETCHARSET(XDOC
,'UTF-8');
end;
/* Создание ответа */
function CREATERESPONSE(XCONTENT in DBMS_XMLDOM.DOMNODE) return clob is
XMAIN_NODE DBMS_XMLDOM.DOMNODE;
XENVELOPE_EL DBMS_XMLDOM.DOMELEMENT;
XENVELOPE DBMS_XMLDOM.DOMNODE;
XHEADER DBMS_XMLDOM.DOMNODE;
XBODY DBMS_XMLDOM.DOMNODE;
XNODE DBMS_XMLDOM.DOMNODE;
CDATA clob;
begin
-- Document
XMAIN_NODE := DBMS_XMLDOM.MAKENODE(XDOC);
-- Envelope
XENVELOPE_EL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => SENVELOPE, NS => SSOAPENV);
DBMS_XMLDOM.SETATTRIBUTE(ELEM => XENVELOPE_EL,
name => 'xmlns:soapenv',
NEWVALUE => 'http://schemas.xmlsoap.org/soap/envelope/');
DBMS_XMLDOM.SETATTRIBUTE(ELEM => XENVELOPE_EL, name => 'xmlns:tsd', NEWVALUE => 'http://www.example.org/TSDService/');
XENVELOPE := DBMS_XMLDOM.MAKENODE(XENVELOPE_EL);
DBMS_XMLDOM.SETPREFIX(N => XENVELOPE, PREFIX => SSOAPENV);
XENVELOPE := DBMS_XMLDOM.APPENDCHILD(N => XMAIN_NODE, NEWCHILD => XENVELOPE);
-- Header
XHEADER := CREATENODE(SHEADER, SSOAPENV);
XHEADER := DBMS_XMLDOM.APPENDCHILD(N => XENVELOPE, NEWCHILD => XHEADER);
-- Body
XBODY := CREATENODE(SBODY, SSOAPENV);
XBODY := DBMS_XMLDOM.APPENDCHILD(N => XENVELOPE, NEWCHILD => XBODY);
XNODE := DBMS_XMLDOM.APPENDCHILD(N => XBODY, NEWCHILD => XCONTENT);
-- Создаем CLOB
DBMS_LOB.CREATETEMPORARY(LOB_LOC => CDATA, CACHE => true, DUR => DBMS_LOB.SESSION);
DBMS_XMLDOM.WRITETOCLOB(XDOC, CDATA, 'UTF-8');
DBMS_XMLDOM.FREEDOCUMENT(DOC => XDOC);
return CDATA;
end;
begin
/* Считаем запись очереди */
REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE);
/* Конвертируем в кодировку БД */
CREQ := BLOB2CLOB(LBDATA => REXSQUEUE.MSG);
-- Создаем инстанс XML парсера
XMLPARCER := DBMS_XMLPARSER.NEWPARSER;
-- Считываем XML из запроса
DBMS_XMLPARSER.PARSECLOB(XMLPARCER
,CREQ);
-- Берем XML документ
XDOC := DBMS_XMLPARSER.GETDOCUMENT(XMLPARCER);
-- Считываем Корневой элемент
XENVELOPE := DBMS_XMLDOM.MAKENODE(DBMS_XMLDOM.GETDOCUMENTELEMENT(XDOC));
-- Считываем элемент Body
XBODY := DBMS_XSLPROCESSOR.SELECTSINGLENODE(XENVELOPE
,SBODY);
-- Считываем дочерние элементы к Body
XNODELIST := DBMS_XMLDOM.GETCHILDNODES(XBODY);
-- Берем первый дочерний элемент
XNODE_ROOT := DBMS_XMLDOM.ITEM(XNODELIST
,0);
-- Считаем имя элемента
DBMS_XMLDOM.GETLOCALNAME(XNODE_ROOT
,SNODE);
-- Считываем DeviceID
SREQDEVICEID := GETNODEVAL(XNODE_ROOT
,SDEVICEID);
--CHECK_ID(SREQDEVICEID);
CREATERESPONSEDOC();
if SREQDEVICEID is not null
then
XCHECKAUTHRESPONSE := CREATENODE(SCHECKAUTHRESPONSE
,STSD);
XRESULT := CREATENODE(SRESULT
,STSD
,'true');
XNODE := DBMS_XMLDOM.APPENDCHILD(N => XCHECKAUTHRESPONSE
,NEWCHILD => XRESULT);
CRESPONSE := CREATERESPONSE(XCHECKAUTHRESPONSE);
end if;
/* Возвращаем ответ */
PKG_EXS.PRC_RESP_ARG_BLOB_SET(NIDENT => NIDENT,
SARG => PKG_EXS.SCONT_FLD_BRESP,
BVALUE => CLOB2BLOB(LCDATA => CRESPONSE));
end;
/* Электронная инвентаризация - считывание пользователей */
procedure INV_GETUSERS_XML
(
NIDENT in number, -- Идентификатор процесса
NSRV_TYPE in number, -- Тип сервиса (см. константы PKG_EXS.NSRV_TYPE*)
NEXSQUEUE in number -- Регистрационный номер обрабатываемой позиции очереди обмена
)
is
REXSQUEUE EXSQUEUE%rowtype; -- Запись позиции очереди
/**/
SREQDEVICEID varchar2(30);
XGETUSERSRESPONSE DBMS_XMLDOM.DOMNODE;
XITEM DBMS_XMLDOM.DOMNODE;
XCODE DBMS_XMLDOM.DOMNODE;
XNAME DBMS_XMLDOM.DOMNODE;
XNODE DBMS_XMLDOM.DOMNODE;
CRESPONSE clob;
XDOC DBMS_XMLDOM.DOMDOCUMENT;
/**/
XMLPARCER DBMS_XMLPARSER.PARSER;
XENVELOPE DBMS_XMLDOM.DOMNODE;
XBODY DBMS_XMLDOM.DOMNODE;
XNODELIST DBMS_XMLDOM.DOMNODELIST;
XNODE_ROOT DBMS_XMLDOM.DOMNODE;
SNODE varchar2(100);
CREQ clob;
/**/
STSD constant varchar2(20) := 'tsd';
SGETUSERSRESPONSE constant varchar2(20) := 'GetUsersResponse';
SDEVICEID constant varchar2(20) := 'DeviceID';
SRESULT constant varchar2(20) := 'Result';
SSOAPENV constant varchar2(20) := 'soapenv';
SENVELOPE constant varchar2(20) := 'Envelope';
SHEADER constant varchar2(20) := 'Header';
SBODY constant varchar2(20) := 'Body';
SITEM constant varchar2(20) := 'Item';
SCODE constant varchar2(20) := 'Code';
SNAME constant varchar2(20) := 'Name';
/* Создание ветки XML */
function CREATENODE
(
STAG in varchar2,
SNS in varchar2 default null,
SVAL in varchar2 default null
) return DBMS_XMLDOM.DOMNODE is
XEL DBMS_XMLDOM.DOMELEMENT;
XNODE DBMS_XMLDOM.DOMNODE;
XTEXT DBMS_XMLDOM.DOMNODE;
begin
if SNS is not null then
XEL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => STAG, NS => SNS);
XNODE := DBMS_XMLDOM.MAKENODE(XEL);
DBMS_XMLDOM.SETPREFIX(N => XNODE, PREFIX => SNS);
else
XEL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => STAG);
XNODE := DBMS_XMLDOM.MAKENODE(XEL);
end if;
if SVAL is not null then
XTEXT := DBMS_XMLDOM.APPENDCHILD(XNODE, DBMS_XMLDOM.MAKENODE(DBMS_XMLDOM.CREATETEXTNODE(XDOC, SVAL)));
end if;
return XNODE;
end;
/* Считывание значения ветки XML */
function GETNODEVAL
(
XROOTNODE in DBMS_XMLDOM.DOMNODE,
SPATTERN in varchar2
) return varchar2 is
XNODE DBMS_XMLDOM.DOMNODE;
SVAL varchar2(100);
begin
XNODE := DBMS_XSLPROCESSOR.SELECTSINGLENODE(N => XROOTNODE, PATTERN => SPATTERN);
if DBMS_XMLDOM.ISNULL(XNODE) then
return null;
end if;
SVAL := DBMS_XMLDOM.GETNODEVALUE(DBMS_XMLDOM.GETFIRSTCHILD(N => XNODE));
return SVAL;
end GETNODEVAL;
/* Создание документа для ответа */
procedure CREATERESPONSEDOC is
begin
XDOC := DBMS_XMLDOM.NEWDOMDOCUMENT;
DBMS_XMLDOM.SETVERSION(XDOC
,'1.0" encoding="UTF-8');
DBMS_XMLDOM.SETCHARSET(XDOC
,'UTF-8');
end;
/* Создание ответа */
function CREATERESPONSE(XCONTENT in DBMS_XMLDOM.DOMNODE) return clob is
XMAIN_NODE DBMS_XMLDOM.DOMNODE;
XENVELOPE_EL DBMS_XMLDOM.DOMELEMENT;
XENVELOPE DBMS_XMLDOM.DOMNODE;
XHEADER DBMS_XMLDOM.DOMNODE;
XBODY DBMS_XMLDOM.DOMNODE;
XNODE DBMS_XMLDOM.DOMNODE;
CDATA clob;
begin
-- Document
XMAIN_NODE := DBMS_XMLDOM.MAKENODE(XDOC);
-- Envelope
XENVELOPE_EL := DBMS_XMLDOM.CREATEELEMENT(DOC => XDOC, TAGNAME => SENVELOPE, NS => SSOAPENV);
DBMS_XMLDOM.SETATTRIBUTE(ELEM => XENVELOPE_EL,
name => 'xmlns:soapenv',
NEWVALUE => 'http://schemas.xmlsoap.org/soap/envelope/');
DBMS_XMLDOM.SETATTRIBUTE(ELEM => XENVELOPE_EL, name => 'xmlns:tsd', NEWVALUE => 'http://www.example.org/TSDService/');
XENVELOPE := DBMS_XMLDOM.MAKENODE(XENVELOPE_EL);
DBMS_XMLDOM.SETPREFIX(N => XENVELOPE, PREFIX => SSOAPENV);
XENVELOPE := DBMS_XMLDOM.APPENDCHILD(N => XMAIN_NODE, NEWCHILD => XENVELOPE);
-- Header
XHEADER := CREATENODE(SHEADER, SSOAPENV);
XHEADER := DBMS_XMLDOM.APPENDCHILD(N => XENVELOPE, NEWCHILD => XHEADER);
-- Body
XBODY := CREATENODE(SBODY, SSOAPENV);
XBODY := DBMS_XMLDOM.APPENDCHILD(N => XENVELOPE, NEWCHILD => XBODY);
XNODE := DBMS_XMLDOM.APPENDCHILD(N => XBODY, NEWCHILD => XCONTENT);
-- Создаем CLOB
DBMS_LOB.CREATETEMPORARY(LOB_LOC => CDATA, CACHE => true, DUR => DBMS_LOB.SESSION);
DBMS_XMLDOM.WRITETOCLOB(XDOC, CDATA, 'UTF-8');
DBMS_XMLDOM.FREEDOCUMENT(DOC => XDOC);
return CDATA;
end;
begin
/* Считаем запись очереди */
REXSQUEUE := GET_EXSQUEUE_ID(NFLAG_SMART => 0, NRN => NEXSQUEUE);
/* Конвертируем в кодировку БД */
CREQ := BLOB2CLOB(LBDATA => REXSQUEUE.MSG);
-- Создаем инстанс XML парсера
XMLPARCER := DBMS_XMLPARSER.NEWPARSER;
-- Считываем XML из запроса
DBMS_XMLPARSER.PARSECLOB(XMLPARCER
,CREQ);
-- Берем XML документ
XDOC := DBMS_XMLPARSER.GETDOCUMENT(XMLPARCER);
-- Считываем Корневой элемент
XENVELOPE := DBMS_XMLDOM.MAKENODE(DBMS_XMLDOM.GETDOCUMENTELEMENT(XDOC));
-- Считываем элемент Body
XBODY := DBMS_XSLPROCESSOR.SELECTSINGLENODE(XENVELOPE
,SBODY);
-- Считываем дочерние элементы к Body
XNODELIST := DBMS_XMLDOM.GETCHILDNODES(XBODY);
-- Берем первый дочерний элемент
XNODE_ROOT := DBMS_XMLDOM.ITEM(XNODELIST
,0);
-- Считаем имя элемента
DBMS_XMLDOM.GETLOCALNAME(XNODE_ROOT
,SNODE);
-- Считываем DeviceID
SREQDEVICEID := GETNODEVAL(XNODE_ROOT
,SDEVICEID);
--CHECK_ID(SREQDEVICEID);
CREATERESPONSEDOC();
if SREQDEVICEID is not null
then
XGETUSERSRESPONSE := CREATENODE(SGETUSERSRESPONSE
,STSD);
for REC in (select T.RN
,A.AGNABBR
from INVPERSONS T
,AGNLIST A
where T.COMPANY = 136018
and T.AGNLIST = A.RN)
loop
XITEM := CREATENODE(SITEM
,STSD);
XCODE := CREATENODE(SCODE
,STSD
,REC.RN);
XNAME := CREATENODE(SNAME
,STSD
,REC.AGNABBR);
XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM
,NEWCHILD => XCODE);
XNODE := DBMS_XMLDOM.APPENDCHILD(N => XITEM
,NEWCHILD => XNAME);
XNODE := DBMS_XMLDOM.APPENDCHILD(N => XGETUSERSRESPONSE
,NEWCHILD => XITEM);
end loop;
CRESPONSE := CREATERESPONSE(XGETUSERSRESPONSE);
end if;
/* Возвращаем ответ */
PKG_EXS.PRC_RESP_ARG_BLOB_SET(NIDENT => NIDENT,
SARG => PKG_EXS.SCONT_FLD_BRESP,
BVALUE => CLOB2BLOB(LCDATA => CRESPONSE, sCHARSET => 'UTF8'));
end;
end;
/