forked from CITKParus/P8-Panels
ЦИТК-979 - Формирование SQL-выражения для запроса (сервер, начало)
This commit is contained in:
parent
5706d59a92
commit
aa9568c2fa
@ -14,7 +14,8 @@ create table P8PNL_QE_QUERY
|
|||||||
OPT clob, -- Настройка запроса
|
OPT clob, -- Настройка запроса
|
||||||
ENTS clob, -- Сущности запроса
|
ENTS clob, -- Сущности запроса
|
||||||
RLS clob, -- Отношения сущностей запроса
|
RLS clob, -- Отношения сущностей запроса
|
||||||
QRY clob, -- Запрос
|
QRY clob, -- Запрос (SQL выражение)
|
||||||
|
QRY_MSG clob, -- Сообщение при формировании запроса (предупреждения и ошибки формирования)
|
||||||
constraint C_P8PNL_QE_QUERY_RN_PK primary key (RN),
|
constraint C_P8PNL_QE_QUERY_RN_PK primary key (RN),
|
||||||
constraint C_P8PNL_QE_QUERY_CODE_NB check (rtrim(CODE) is not null),
|
constraint C_P8PNL_QE_QUERY_CODE_NB check (rtrim(CODE) is not null),
|
||||||
constraint C_P8PNL_QE_QUERY_NAME_NB check (rtrim(NAME) is not null),
|
constraint C_P8PNL_QE_QUERY_NAME_NB check (rtrim(NAME) is not null),
|
||||||
|
|||||||
@ -271,6 +271,8 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
is
|
is
|
||||||
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||||
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
|
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
|
||||||
|
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||||
|
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||||
begin
|
begin
|
||||||
/* Провим права доступа */
|
/* Провим права доступа */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
||||||
@ -282,6 +284,9 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
PKG_P8PANELS_QE_BASE.TENTS_ADD(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);
|
PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
|
||||||
|
/* Переформируем SQL-выражение */
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_SQL_BUILD(NRN => RQ.RN, SQRY => SQRY, SQRY_MSG => SQRY_MSG);
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_QRY_SET(NRN => RQ.RN, CQRY => SQRY, CQRY_MSG => SQRY_MSG);
|
||||||
end QUERY_ENT_ADD;
|
end QUERY_ENT_ADD;
|
||||||
|
|
||||||
/* Удаление сущности из запроса */
|
/* Удаление сущности из запроса */
|
||||||
@ -295,6 +300,8 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
|
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
|
||||||
RENT PKG_P8PANELS_QE_BASE.TENT; -- Удаляемая сущность
|
RENT PKG_P8PANELS_QE_BASE.TENT; -- Удаляемая сущность
|
||||||
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
||||||
|
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||||
|
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||||
begin
|
begin
|
||||||
/* Провим права доступа */
|
/* Провим права доступа */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
||||||
@ -328,6 +335,9 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
|
PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
|
||||||
/* Сохраняем обновленный набор связей */
|
/* Сохраняем обновленный набор связей */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
|
PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
|
||||||
|
/* Переформируем SQL-выражение */
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_SQL_BUILD(NRN => RQ.RN, SQRY => SQRY, SQRY_MSG => SQRY_MSG);
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_QRY_SET(NRN => RQ.RN, CQRY => SQRY, CQRY_MSG => SQRY_MSG);
|
||||||
end QUERY_ENT_REMOVE;
|
end QUERY_ENT_REMOVE;
|
||||||
|
|
||||||
/* Установка координат сущности в редакторе диаграммы запроса */
|
/* Установка координат сущности в редакторе диаграммы запроса */
|
||||||
@ -382,7 +392,9 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
|
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
|
||||||
NENT_INDEX PKG_STD.TNUMBER; -- Индекс изменяемой сущности
|
NENT_INDEX PKG_STD.TNUMBER; -- Индекс изменяемой сущности
|
||||||
RATTRS PKG_P8PANELS_QE_BASE.TATTRS; -- Коллекция полученных атриубтов
|
RATTRS PKG_P8PANELS_QE_BASE.TATTRS; -- Коллекция полученных атриубтов
|
||||||
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
||||||
|
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||||
|
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||||
begin
|
begin
|
||||||
/* Провим права доступа */
|
/* Провим права доступа */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
||||||
@ -424,6 +436,9 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
|
PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
|
||||||
/* Сохраняем обновленный набор связей */
|
/* Сохраняем обновленный набор связей */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
|
PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
|
||||||
|
/* Переформируем SQL-выражение */
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_SQL_BUILD(NRN => RQ.RN, SQRY => SQRY, SQRY_MSG => SQRY_MSG);
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_QRY_SET(NRN => RQ.RN, CQRY => SQRY, CQRY_MSG => SQRY_MSG);
|
||||||
end QUERY_ENT_ATTRS_SET;
|
end QUERY_ENT_ATTRS_SET;
|
||||||
|
|
||||||
/* Добавление связи в запрос */
|
/* Добавление связи в запрос */
|
||||||
@ -436,6 +451,8 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
is
|
is
|
||||||
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||||
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
||||||
|
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||||
|
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||||
begin
|
begin
|
||||||
/* Провим права доступа */
|
/* Провим права доступа */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
||||||
@ -447,6 +464,9 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
PKG_P8PANELS_QE_BASE.TRLS_ADD(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);
|
PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
|
||||||
|
/* Переформируем SQL-выражение */
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_SQL_BUILD(NRN => RQ.RN, SQRY => SQRY, SQRY_MSG => SQRY_MSG);
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_QRY_SET(NRN => RQ.RN, CQRY => SQRY, CQRY_MSG => SQRY_MSG);
|
||||||
end QUERY_RL_ADD;
|
end QUERY_RL_ADD;
|
||||||
|
|
||||||
/* Удаление связи из запроса */
|
/* Удаление связи из запроса */
|
||||||
@ -458,6 +478,8 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
is
|
is
|
||||||
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||||
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
||||||
|
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||||
|
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||||
begin
|
begin
|
||||||
/* Провим права доступа */
|
/* Провим права доступа */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
||||||
@ -469,6 +491,9 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
PKG_P8PANELS_QE_BASE.TRLS_REMOVE(RRLS => RRLS, SID => SID);
|
PKG_P8PANELS_QE_BASE.TRLS_REMOVE(RRLS => RRLS, SID => SID);
|
||||||
/* Сохраняем обновленный набор связей */
|
/* Сохраняем обновленный набор связей */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
|
PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
|
||||||
|
/* Переформируем SQL-выражение */
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_SQL_BUILD(NRN => RQ.RN, SQRY => SQRY, SQRY_MSG => SQRY_MSG);
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_QRY_SET(NRN => RQ.RN, CQRY => SQRY, CQRY_MSG => SQRY_MSG);
|
||||||
end QUERY_RL_REMOVE;
|
end QUERY_RL_REMOVE;
|
||||||
|
|
||||||
/* Добавление аргумента запроса */
|
/* Добавление аргумента запроса */
|
||||||
@ -577,6 +602,8 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
is
|
is
|
||||||
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||||
ROPT PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса
|
ROPT PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса
|
||||||
|
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||||
|
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||||
begin
|
begin
|
||||||
/* Провим права доступа */
|
/* Провим права доступа */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
|
||||||
@ -588,6 +615,9 @@ create or replace package body PKG_P8PANELS_QE as
|
|||||||
ROPT.SCOND := SCOND;
|
ROPT.SCOND := SCOND;
|
||||||
/* Сохраняем обновленную настройку */
|
/* Сохраняем обновленную настройку */
|
||||||
PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT);
|
PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT);
|
||||||
|
/* Переформируем SQL-выражение */
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_SQL_BUILD(NRN => RQ.RN, SQRY => SQRY, SQRY_MSG => SQRY_MSG);
|
||||||
|
PKG_P8PANELS_QE_BASE.QUERY_QRY_SET(NRN => RQ.RN, CQRY => SQRY, CQRY_MSG => SQRY_MSG);
|
||||||
end QUERY_OPT_COND_SET;
|
end QUERY_OPT_COND_SET;
|
||||||
|
|
||||||
end PKG_P8PANELS_QE;
|
end PKG_P8PANELS_QE;
|
||||||
|
|||||||
@ -301,6 +301,22 @@ create or replace package PKG_P8PANELS_QE_BASE as
|
|||||||
NRN in number, -- Рег. номер запроса
|
NRN in number, -- Рег. номер запроса
|
||||||
ROPT in TOPT -- Настройка запроса
|
ROPT in TOPT -- Настройка запроса
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Запись SQL-выражения запроса */
|
||||||
|
procedure QUERY_QRY_SET
|
||||||
|
(
|
||||||
|
NRN in number, -- Рег. номер запроса
|
||||||
|
CQRY in clob, -- SQL-выражение
|
||||||
|
CQRY_MSG in clob -- Сообщение при формировании SQL-выражения (предупреждения и ошибки формирования)
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Формирование SQL запроса */
|
||||||
|
procedure QUERY_SQL_BUILD
|
||||||
|
(
|
||||||
|
NRN in number, -- Рег. номер запроса
|
||||||
|
SQRY out varchar2, -- SQL-выражение
|
||||||
|
SQRY_MSG out varchar2 -- Сообщение при формировании SQL-выражения (предупреждения и ошибки формирования)
|
||||||
|
);
|
||||||
|
|
||||||
end PKG_P8PANELS_QE_BASE;
|
end PKG_P8PANELS_QE_BASE;
|
||||||
/
|
/
|
||||||
@ -324,6 +340,8 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
|||||||
STAG_RL constant PKG_STD.TSTRING := 'XRL'; -- Связь
|
STAG_RL constant PKG_STD.TSTRING := 'XRL'; -- Связь
|
||||||
STAG_OPT constant PKG_STD.TSTRING := 'XOPT'; -- Настройка запроса
|
STAG_OPT constant PKG_STD.TSTRING := 'XOPT'; -- Настройка запроса
|
||||||
STAG_COND constant PKG_STD.TSTRING := 'XCOND'; -- Условия запроса
|
STAG_COND constant PKG_STD.TSTRING := 'XCOND'; -- Условия запроса
|
||||||
|
STAG_QRY constant PKG_STD.TSTRING := 'XQRY'; -- SQL-выражение запроса
|
||||||
|
STAG_QRY_MSG constant PKG_STD.TSTRING := 'XQRY_MSG'; -- Сообщение при формировании запроса
|
||||||
|
|
||||||
/* Константы - Атрибуты для сериализации */
|
/* Константы - Атрибуты для сериализации */
|
||||||
SATTR_ID constant PKG_STD.TSTRING := 'id'; -- Идентификатор
|
SATTR_ID constant PKG_STD.TSTRING := 'id'; -- Идентификатор
|
||||||
@ -839,6 +857,33 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
|||||||
/* Вернём результат */
|
/* Вернём результат */
|
||||||
return RRES;
|
return RRES;
|
||||||
end TATTR_FROM_XML;
|
end TATTR_FROM_XML;
|
||||||
|
|
||||||
|
/* Поиск индекса атрибута по идентификатору */
|
||||||
|
function TATTRS_INDEX_BY_ID
|
||||||
|
(
|
||||||
|
RATTRS in TATTRS, -- Коллекция атрибутов
|
||||||
|
SID in varchar2 -- Искомый идентификатор
|
||||||
|
) return number -- Индекс найденного атрибута (null - если не найдено)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
/* Обходим коллекцию */
|
||||||
|
if ((RATTRS is not null) and (RATTRS.COUNT > 0)) then
|
||||||
|
for I in RATTRS.FIRST .. RATTRS.LAST
|
||||||
|
loop
|
||||||
|
begin
|
||||||
|
/* Возвращаем найденный индекс */
|
||||||
|
if (RATTRS(I).SID = SID) then
|
||||||
|
return I;
|
||||||
|
end if;
|
||||||
|
exception
|
||||||
|
when NO_DATA_FOUND then
|
||||||
|
null;
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
/* Ничего не нашли */
|
||||||
|
return null;
|
||||||
|
end TATTRS_INDEX_BY_ID;
|
||||||
|
|
||||||
/* Поиск индекса атрибута по имени */
|
/* Поиск индекса атрибута по имени */
|
||||||
function TATTRS_INDEX_BY_NAME
|
function TATTRS_INDEX_BY_NAME
|
||||||
@ -1212,6 +1257,33 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
|||||||
return null;
|
return null;
|
||||||
end TENTS_INDEX_BY_ID;
|
end TENTS_INDEX_BY_ID;
|
||||||
|
|
||||||
|
/* Поиск индекса сущности по идентификатору атрибута */
|
||||||
|
function TENTS_INDEX_BY_ATTR_ID
|
||||||
|
(
|
||||||
|
RENTS in TENTS, -- Коллекция сущностей
|
||||||
|
SATTR_ID in varchar2 -- Искомый идентификатор атрибута
|
||||||
|
) return number -- Индекс найденной сущности (null - если не найдено)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
/* Обходим коллекцию */
|
||||||
|
if ((RENTS is not null) and (RENTS.COUNT > 0)) then
|
||||||
|
for I in RENTS.FIRST .. RENTS.LAST
|
||||||
|
loop
|
||||||
|
begin
|
||||||
|
/* Возвращаем найденный индекс */
|
||||||
|
if (TATTRS_INDEX_BY_ID(RATTRS => RENTS(I).RATTRS, SID => SATTR_ID) is not null) then
|
||||||
|
return I;
|
||||||
|
end if;
|
||||||
|
exception
|
||||||
|
when NO_DATA_FOUND then
|
||||||
|
null;
|
||||||
|
end;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
/* Ничего не нашли */
|
||||||
|
return null;
|
||||||
|
end TENTS_INDEX_BY_ATTR_ID;
|
||||||
|
|
||||||
/* Поиск номера сущности в коллекции */
|
/* Поиск номера сущности в коллекции */
|
||||||
function TENTS_NEXT_NUMB
|
function TENTS_NEXT_NUMB
|
||||||
(
|
(
|
||||||
@ -2071,6 +2143,10 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
|||||||
if (RQ.RLS is not null) then
|
if (RQ.RLS is not null) then
|
||||||
TRLS_TO_XML(RRLS => QUERY_RLS_FROM_XML(CXML => RQ.RLS));
|
TRLS_TO_XML(RRLS => QUERY_RLS_FROM_XML(CXML => RQ.RLS));
|
||||||
end if;
|
end if;
|
||||||
|
/* SQL-выражение */
|
||||||
|
PKG_XFAST.HERB(SNAME => STAG_QRY, LCVALUE => RQ.QRY);
|
||||||
|
/* Сообщение при формировании SQL-выражения */
|
||||||
|
PKG_XFAST.HERB(SNAME => STAG_QRY_MSG, LCVALUE => RQ.QRY_MSG);
|
||||||
/* Закрываем корень */
|
/* Закрываем корень */
|
||||||
PKG_XFAST.UP();
|
PKG_XFAST.UP();
|
||||||
/* Сериализуем */
|
/* Сериализуем */
|
||||||
@ -2419,5 +2495,265 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
|||||||
QUERY_CH_DATE_SYNC(NRN => NRN);
|
QUERY_CH_DATE_SYNC(NRN => NRN);
|
||||||
end QUERY_OPT_SET;
|
end QUERY_OPT_SET;
|
||||||
|
|
||||||
|
/* Запись SQL-выражения запроса */
|
||||||
|
procedure QUERY_QRY_SET
|
||||||
|
(
|
||||||
|
NRN in number, -- Рег. номер запроса
|
||||||
|
CQRY in clob, -- SQL-выражение
|
||||||
|
CQRY_MSG in clob -- Сообщение при формировании SQL-выражения (предупреждения и ошибки формирования)
|
||||||
|
)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
/* Сохраним её */
|
||||||
|
update P8PNL_QE_QUERY T
|
||||||
|
set T.QRY = CQRY,
|
||||||
|
T.QRY_MSG = CQRY_MSG
|
||||||
|
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_QRY_SET;
|
||||||
|
|
||||||
|
/* Формирование SQL запроса */
|
||||||
|
procedure QUERY_SQL_BUILD
|
||||||
|
(
|
||||||
|
NRN in number, -- Рег. номер запроса
|
||||||
|
SQRY out varchar2, -- SQL-выражение
|
||||||
|
SQRY_MSG out varchar2 -- Сообщение при формировании SQL-выражения (предупреждения и ошибки формирования)
|
||||||
|
)
|
||||||
|
is
|
||||||
|
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||||
|
RENTS TENTS; -- Сущности запроса
|
||||||
|
RRLS TRLS; -- Связи запроса
|
||||||
|
ROPT TOPT; -- Настройка запроса
|
||||||
|
|
||||||
|
/* Кумулятивная установка сообщения формирования запроса */
|
||||||
|
procedure SET_MSG
|
||||||
|
(
|
||||||
|
SMESSAGE in varchar2, -- Текст сообщения
|
||||||
|
BCLEAR_QRY in boolean := true -- Флаг очистки сформированного запроса
|
||||||
|
)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
if (BCLEAR_QRY) then
|
||||||
|
SQRY := null;
|
||||||
|
end if;
|
||||||
|
if (SQRY_MSG is null) then
|
||||||
|
SQRY_MSG := SMESSAGE;
|
||||||
|
else
|
||||||
|
SQRY_MSG := SQRY_MSG || CHR(10) || CHR(13) || SMESSAGE;
|
||||||
|
end if;
|
||||||
|
end SET_MSG;
|
||||||
|
|
||||||
|
/* Поиск корневой (не имеет связей по выходу - т.е. нигде не является источником) сущности запроса */
|
||||||
|
procedure FIND_ROOT_ENT
|
||||||
|
(
|
||||||
|
RENTS TENTS, -- Сущности запроса
|
||||||
|
RRLS TRLS, -- Связи запроса
|
||||||
|
RENT out TENT, -- Найденная корневая сущность
|
||||||
|
SMESSAGE out varchar2 -- Сообщение от алгоритма поиска
|
||||||
|
)
|
||||||
|
is
|
||||||
|
BFOUND boolean; -- Флаг наличия атрибута сущности в составе источникв связей запроса
|
||||||
|
begin
|
||||||
|
/* Если сущность одна - то она и главная */
|
||||||
|
if (RENTS.COUNT = 1) then
|
||||||
|
RENT := RENTS(RENTS.FIRST);
|
||||||
|
end if;
|
||||||
|
/* Обходим все сущности */
|
||||||
|
for E in RENTS.FIRST .. RENTS.LAST
|
||||||
|
loop
|
||||||
|
/* Сброс флага наличия атрибутов в источниках связей */
|
||||||
|
BFOUND := false;
|
||||||
|
/* Обходим атрибуты сущности */
|
||||||
|
for A in RENTS(E).RATTRS.FIRST .. RENTS(E).RATTRS.LAST
|
||||||
|
loop
|
||||||
|
/* Обойдем связи и поищем атрибут среди источников */
|
||||||
|
for R in RRLS.FIRST .. RRLS.LAST
|
||||||
|
loop
|
||||||
|
if (RRLS(R).SSOURCE = RENTS(E).RATTRS(A).SID) then
|
||||||
|
BFOUND := true;
|
||||||
|
exit;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
/* Если хоть один атрибут сущности есть среди источников - дальше можно атрибуты этой сущности не рассматривать */
|
||||||
|
exit when BFOUND = true;
|
||||||
|
end loop;
|
||||||
|
/* Если ни один из атрибутов не был источником - сущность наш клиент */
|
||||||
|
if (not BFOUND) then
|
||||||
|
/* Если мы ещё не находили корневую сущность ранее */
|
||||||
|
if (RENT.SID is null) then
|
||||||
|
RENT := RENTS(E);
|
||||||
|
else
|
||||||
|
/* Ранее была найдена корневая сущность */
|
||||||
|
SMESSAGE := 'В запросе более одной корневой (без выходных связей) сущности.';
|
||||||
|
return;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
/* Проверим, что хоть что-то нашли */
|
||||||
|
if (RENT.SID is null) then
|
||||||
|
SMESSAGE := 'В запросе нет корневой (без выходных связей) сущности.';
|
||||||
|
end if;
|
||||||
|
end FIND_ROOT_ENT;
|
||||||
|
|
||||||
|
/* Формирование части "select" */
|
||||||
|
procedure BUILD_SELECT
|
||||||
|
(
|
||||||
|
RENTS TENTS, -- Сущности запроса
|
||||||
|
SQRY in out varchar2 -- Буфер для запроса
|
||||||
|
)
|
||||||
|
is
|
||||||
|
SFIELD PKG_STD.TSTRING; -- Буфер для поля запроса
|
||||||
|
begin
|
||||||
|
PKG_SQL_BUILD.APPEND(SSQL => SQRY, SELEMENT1 => 'select ');
|
||||||
|
for I in RENTS.FIRST .. RENTS.LAST
|
||||||
|
loop
|
||||||
|
if ((RENTS(I).RATTRS is not null) and (RENTS(I).RATTRS.COUNT > 0)) then
|
||||||
|
for J in RENTS(I).RATTRS.FIRST .. RENTS(I).RATTRS.LAST
|
||||||
|
loop
|
||||||
|
if (RENTS(I).RATTRS(J).NSHOW = 1) then
|
||||||
|
SFIELD := RENTS(I).RATTRS(J).SID || ' ' || RENTS(I).RATTRS(J).SNAME || I || J;
|
||||||
|
if (not ((I = RENTS.LAST) and (J = RENTS(I).RATTRS.LAST))) then
|
||||||
|
SFIELD := SFIELD || ', ';
|
||||||
|
end if;
|
||||||
|
PKG_SQL_BUILD.APPEND(SSQL => SQRY, SELEMENT1 => SFIELD);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end BUILD_SELECT;
|
||||||
|
|
||||||
|
/* Формирование иерархии связей в секции "from" */
|
||||||
|
procedure BUILD_FROM_HIER
|
||||||
|
(
|
||||||
|
RENT_START TENT, -- Начало ветки
|
||||||
|
RENTS TENTS, -- Сущности запроса
|
||||||
|
RRLS TRLS, -- Связи запроса
|
||||||
|
SQRY in out varchar2 -- Буфер для запроса
|
||||||
|
)
|
||||||
|
is
|
||||||
|
NENT_SRC PKG_STD.TNUMBER; -- Индекс сущности-источника связи
|
||||||
|
STABLE PKG_STD.TSTRING; -- Буфер для таблицы запроса
|
||||||
|
begin
|
||||||
|
/* Обходим связи */
|
||||||
|
for I in RRLS.FIRST .. RRLS.LAST
|
||||||
|
loop
|
||||||
|
/* Если это связь, в которой приёмником является стартовая сущность */
|
||||||
|
if (TATTRS_INDEX_BY_ID(RATTRS => RENT_START.RATTRS, SID => RRLS(I).STARGET) is not null) then
|
||||||
|
/* Найдем сущность-источник связи по атрибуту-источнику связи */
|
||||||
|
NENT_SRC := TENTS_INDEX_BY_ATTR_ID(RENTS => RENTS, SATTR_ID => RRLS(I).SSOURCE);
|
||||||
|
if (NENT_SRC is null) then
|
||||||
|
P_EXCEPTION(0,
|
||||||
|
'Для связи "%s - %s" не удалось определить сущность-источник.',
|
||||||
|
RRLS (I)
|
||||||
|
.SSOURCE,
|
||||||
|
RRLS (I)
|
||||||
|
.STARGET);
|
||||||
|
end if;
|
||||||
|
/* Соберем выражение и добавим его в запрос */
|
||||||
|
STABLE := 'left join ' || RENTS(NENT_SRC).SNAME || ' ' || RENTS(NENT_SRC).SID || ' on ' || RRLS(I).STARGET ||
|
||||||
|
' = ' || RRLS(I).SSOURCE;
|
||||||
|
PKG_SQL_BUILD.APPEND(SSQL => SQRY, SELEMENT1 => STABLE);
|
||||||
|
/* Добавим связи сущности-источника */
|
||||||
|
BUILD_FROM_HIER(RENT_START => RENTS(NENT_SRC), RENTS => RENTS, RRLS => RRLS, SQRY => SQRY);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end BUILD_FROM_HIER;
|
||||||
|
|
||||||
|
/* Формирование части "from" */
|
||||||
|
procedure BUILD_FROM
|
||||||
|
(
|
||||||
|
RENTS TENTS, -- Сущности запроса
|
||||||
|
RRLS TRLS, -- Связи запроса
|
||||||
|
SQRY in out varchar2 -- Буфер для запроса
|
||||||
|
)
|
||||||
|
is
|
||||||
|
RENT_ROOT TENT; -- Корневая сущность запроса
|
||||||
|
STABLE PKG_STD.TSTRING; -- Буфер для таблицы запроса
|
||||||
|
SMESSAGE PKG_STD.TSTRING; -- Буфер для сообщений
|
||||||
|
begin
|
||||||
|
/* Определяем корневую сущность запроса */
|
||||||
|
FIND_ROOT_ENT(RENTS => RENTS, RRLS => RRLS, RENT => RENT_ROOT, SMESSAGE => SMESSAGE);
|
||||||
|
/* Продолжаем только если корневую успешно определили */
|
||||||
|
if ((RENT_ROOT.SID is not null) and (SMESSAGE is null)) then
|
||||||
|
PKG_SQL_BUILD.APPEND(SSQL => SQRY, SELEMENT1 => 'from ');
|
||||||
|
STABLE := RENT_ROOT.SNAME || ' ' || RENT_ROOT.SID;
|
||||||
|
PKG_SQL_BUILD.APPEND(SSQL => SQRY, SELEMENT1 => STABLE);
|
||||||
|
if (RRLS.COUNT > 0) then
|
||||||
|
BUILD_FROM_HIER(RENT_START => RENT_ROOT, RENTS => RENTS, RRLS => RRLS, SQRY => SQRY);
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
/* Корневую сущность не нашли */
|
||||||
|
SET_MSG(SMESSAGE => SMESSAGE, BCLEAR_QRY => false);
|
||||||
|
end if;
|
||||||
|
end BUILD_FROM;
|
||||||
|
|
||||||
|
/* Формирование части "where" */
|
||||||
|
procedure BUILD_WHERE
|
||||||
|
(
|
||||||
|
ROPT TOPT, -- Настройка запроса
|
||||||
|
SQRY in out varchar2 -- Буфер для запроса
|
||||||
|
)
|
||||||
|
is
|
||||||
|
begin
|
||||||
|
if (ROPT.SCOND is not null) then
|
||||||
|
PKG_SQL_BUILD.APPEND(SSQL => SQRY, SELEMENT1 => 'where ' || ROPT.SCOND);
|
||||||
|
end if;
|
||||||
|
end BUILD_WHERE;
|
||||||
|
begin
|
||||||
|
/*
|
||||||
|
TODO: owner="root" created="09.09.2025"
|
||||||
|
text="Контроль длины псевдонима таблицы и поля (максимум 30 символов)"
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
TODO: owner="root" created="10.09.2025"
|
||||||
|
text="Предусмотреть связям признак ""обязательность""
|
||||||
|
с ним - join
|
||||||
|
без него - left join"
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
TODO: owner="root" created="10.09.2025"
|
||||||
|
text="Предусмотреть отладочные значения для аргументов запроса"
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
TODO: owner="root" created="11.09.2025"
|
||||||
|
text="Проверять соответствие условий отбора запроса набору его аргументов"
|
||||||
|
*/
|
||||||
|
/* Читаем описание запроса */
|
||||||
|
RQ := QUERY_GET(NRN => NRN);
|
||||||
|
/* Читаем сущности запроса */
|
||||||
|
RENTS := QUERY_ENTS_GET(CENTS => RQ.ENTS);
|
||||||
|
/* Нет сущностей - нет запроса */
|
||||||
|
if ((RENTS is null) and (RENTS.COUNT = 0)) then
|
||||||
|
SET_MSG(SMESSAGE => 'В запросе нет сущностей.');
|
||||||
|
return;
|
||||||
|
end if;
|
||||||
|
/* Читаем связи запроса */
|
||||||
|
RRLS := QUERY_RLS_GET(CRLS => RQ.RLS);
|
||||||
|
/* Нельзя построить запрос, если есть несвязанные сущности */
|
||||||
|
if ((RENTS.COUNT > 1) and (RENTS.COUNT - 1 > RRLS.COUNT)) then
|
||||||
|
SET_MSG(SMESSAGE => 'В запросе есть несвязанные сущности.');
|
||||||
|
return;
|
||||||
|
end if;
|
||||||
|
/* Читаем настройку запроса */
|
||||||
|
ROPT := QUERY_OPT_GET(COPT => RQ.OPT);
|
||||||
|
/* Добавляем подсказку совместимости */
|
||||||
|
SQRY := PKG_SQL_BUILD.COMPATIBLE(SSQL => SQRY);
|
||||||
|
/* Собираем запрос - поля */
|
||||||
|
BUILD_SELECT(RENTS => RENTS, SQRY => SQRY);
|
||||||
|
/* Собираем запрос - таблицы и связи */
|
||||||
|
BUILD_FROM(RENTS => RENTS, RRLS => RRLS, SQRY => SQRY);
|
||||||
|
/* Собираем запрос - условия */
|
||||||
|
BUILD_WHERE(ROPT => ROPT, SQRY => SQRY);
|
||||||
|
exception
|
||||||
|
when others then
|
||||||
|
PKG_STATE.DIAGNOSTICS_STACKED();
|
||||||
|
SET_MSG(SMESSAGE => PKG_STATE.SQL_ERRM(), BCLEAR_QRY => false);
|
||||||
|
end QUERY_SQL_BUILD;
|
||||||
|
|
||||||
end PKG_P8PANELS_QE_BASE;
|
end PKG_P8PANELS_QE_BASE;
|
||||||
/
|
/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user