ЦИТК-979 - Формирование SQL-выражения для запроса (сервер, начало)
This commit is contained in:
parent
5706d59a92
commit
aa9568c2fa
@ -14,7 +14,8 @@ create table P8PNL_QE_QUERY
|
||||
OPT clob, -- Настройка запроса
|
||||
ENTS 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_CODE_NB check (rtrim(CODE) 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
|
||||
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
|
||||
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||
begin
|
||||
/* Провим права доступа */
|
||||
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.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;
|
||||
|
||||
/* Удаление сущности из запроса */
|
||||
@ -295,6 +300,8 @@ create or replace package body PKG_P8PANELS_QE as
|
||||
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
|
||||
RENT PKG_P8PANELS_QE_BASE.TENT; -- Удаляемая сущность
|
||||
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
||||
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||
begin
|
||||
/* Провим права доступа */
|
||||
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_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;
|
||||
|
||||
/* Установка координат сущности в редакторе диаграммы запроса */
|
||||
@ -383,6 +393,8 @@ create or replace package body PKG_P8PANELS_QE as
|
||||
NENT_INDEX PKG_STD.TNUMBER; -- Индекс изменяемой сущности
|
||||
RATTRS PKG_P8PANELS_QE_BASE.TATTRS; -- Коллекция полученных атриубтов
|
||||
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
||||
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||
begin
|
||||
/* Провим права доступа */
|
||||
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_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;
|
||||
|
||||
/* Добавление связи в запрос */
|
||||
@ -436,6 +451,8 @@ create or replace package body PKG_P8PANELS_QE as
|
||||
is
|
||||
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
||||
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||
begin
|
||||
/* Провим права доступа */
|
||||
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.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;
|
||||
|
||||
/* Удаление связи из запроса */
|
||||
@ -458,6 +478,8 @@ create or replace package body PKG_P8PANELS_QE as
|
||||
is
|
||||
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
|
||||
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||
begin
|
||||
/* Провим права доступа */
|
||||
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.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;
|
||||
|
||||
/* Добавление аргумента запроса */
|
||||
@ -577,6 +602,8 @@ create or replace package body PKG_P8PANELS_QE as
|
||||
is
|
||||
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
|
||||
ROPT PKG_P8PANELS_QE_BASE.TOPT; -- Настройка запроса
|
||||
SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса
|
||||
SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения
|
||||
begin
|
||||
/* Провим права доступа */
|
||||
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;
|
||||
/* Сохраняем обновленную настройку */
|
||||
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 PKG_P8PANELS_QE;
|
||||
|
||||
@ -302,6 +302,22 @@ create or replace package PKG_P8PANELS_QE_BASE as
|
||||
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;
|
||||
/
|
||||
create or replace package body PKG_P8PANELS_QE_BASE as
|
||||
@ -324,6 +340,8 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
||||
STAG_RL constant PKG_STD.TSTRING := 'XRL'; -- Связь
|
||||
STAG_OPT constant PKG_STD.TSTRING := 'XOPT'; -- Настройка запроса
|
||||
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'; -- Идентификатор
|
||||
@ -840,6 +858,33 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
||||
return RRES;
|
||||
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
|
||||
(
|
||||
@ -1212,6 +1257,33 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
||||
return null;
|
||||
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
|
||||
(
|
||||
@ -2071,6 +2143,10 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
||||
if (RQ.RLS is not null) then
|
||||
TRLS_TO_XML(RRLS => QUERY_RLS_FROM_XML(CXML => RQ.RLS));
|
||||
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();
|
||||
/* Сериализуем */
|
||||
@ -2419,5 +2495,265 @@ create or replace package body PKG_P8PANELS_QE_BASE as
|
||||
QUERY_CH_DATE_SYNC(NRN => NRN);
|
||||
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;
|
||||
/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user