From 63e3d3833e8826657e9cc0e1bcd6479758c327a3 Mon Sep 17 00:00:00 2001 From: Mikhail Chechnev Date: Mon, 13 Oct 2025 16:27:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A6=D0=98=D0=A2=D0=9A-979=20-=20=D0=A0=D0=B5?= =?UTF-8?q?=D0=B4=D0=B0=D0=BA=D1=82=D0=BE=D1=80=20=D0=B7=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D0=BE=D0=B2=20-=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=20=D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=82=D0=B2=D0=B8=D1=8F=20=D1=83=D1=81=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=BE=D1=82=D0=B1=D0=BE=D1=80=D0=B0=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0=20=D0=BD=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=D1=83=20=D0=B5=D0=B3=D0=BE=20=D0=B0=D1=80=D0=B3=D1=83?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2,=20=D0=B8=D0=BD=D0=BA?= =?UTF-8?q?=D0=B0=D0=BF=D1=81=D1=83=D0=BB=D1=8F=D1=86=D0=B8=D1=8F=20=D0=BE?= =?UTF-8?q?=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20SQL-?= =?UTF-8?q?=D0=B2=D1=8B=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0=20=D0=B2=20=D0=B1=D0=B0?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=BE=D0=BC=20=D0=BF=D0=B0=D0=BA=D0=B5=D1=82?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/PKG_P8PANELS_QE.pck | 41 ++++++------------- db/PKG_P8PANELS_QE_BASE.pck | 79 +++++++++++++++++++++++++++++-------- 2 files changed, 76 insertions(+), 44 deletions(-) diff --git a/db/PKG_P8PANELS_QE.pck b/db/PKG_P8PANELS_QE.pck index c0929b8..88d0a23 100644 --- a/db/PKG_P8PANELS_QE.pck +++ b/db/PKG_P8PANELS_QE.pck @@ -281,8 +281,6 @@ 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()); @@ -295,8 +293,7 @@ create or replace package body PKG_P8PANELS_QE as /* Сохраняем обновленный набор сущностей */ 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); + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_ENT_ADD; /* Удаление сущности из запроса */ @@ -310,8 +307,6 @@ 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()); @@ -346,8 +341,7 @@ create or replace package body PKG_P8PANELS_QE as /* Сохраняем обновленный набор связей */ 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); + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_ENT_REMOVE; /* Установка координат сущности в редакторе диаграммы запроса */ @@ -404,8 +398,6 @@ create or replace package body PKG_P8PANELS_QE as RATTRS PKG_P8PANELS_QE_BASE.TATTRS; -- Коллекция полученных атриубтов RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей SCHECK_MSG PKG_STD.TLSTRING; -- Сообщение при проверке атрибутов - SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса - SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения begin /* Провим права доступа */ PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER()); @@ -453,8 +445,7 @@ create or replace package body PKG_P8PANELS_QE as /* Сохраняем обновленный набор связей */ 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); + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_ENT_ATTRS_SET; /* Добавление связи в запрос */ @@ -467,8 +458,6 @@ 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()); @@ -481,8 +470,7 @@ create or replace package body PKG_P8PANELS_QE as /* Сохраняем обновленный набор связей */ 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); + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_RL_ADD; /* Удаление связи из запроса */ @@ -494,8 +482,6 @@ 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()); @@ -508,8 +494,7 @@ create or replace package body PKG_P8PANELS_QE as /* Сохраняем обновленный набор связей */ 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); + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_RL_REMOVE; /* Установка признака обязательности связи */ @@ -522,8 +507,6 @@ 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 /* Читаем запись запроса */ RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN); @@ -534,8 +517,7 @@ create or replace package body PKG_P8PANELS_QE as /* Сохраняем обновленный набор связей */ 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); + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_RL_MANDATORY_SET; /* Добавление аргумента запроса */ @@ -567,6 +549,8 @@ create or replace package body PKG_P8PANELS_QE as SVALUE => SVALUE); /* Сохраняем обновленную настройку */ PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT); + /* Переформируем SQL-выражение */ + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_OPT_ARG_ADD; /* Изменение аргумента запроса */ @@ -608,6 +592,8 @@ create or replace package body PKG_P8PANELS_QE as SVALUE => SVALUE); /* Сохраняем обновленную настройку */ PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT); + /* Переформируем SQL-выражение */ + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_OPT_ARG_EDIT; /* Удаление аргумента запроса */ @@ -637,6 +623,8 @@ create or replace package body PKG_P8PANELS_QE as PKG_P8PANELS_QE_BASE.TARGS_REMOVE(RARGS => ROPT.RARGS, SNAME => SNAME); /* Сохраняем обновленную настройку */ PKG_P8PANELS_QE_BASE.QUERY_OPT_SET(NRN => RQ.RN, ROPT => ROPT); + /* Переформируем SQL-выражение */ + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_OPT_ARG_REMOVE; /* Установка условий отбора запроса */ @@ -648,8 +636,6 @@ 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()); @@ -662,8 +648,7 @@ create or replace package body PKG_P8PANELS_QE as /* Сохраняем обновленную настройку */ 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); + PKG_P8PANELS_QE_BASE.QUERY_QRY_REFRESH(NRN => RQ.RN); end QUERY_OPT_COND_SET; end PKG_P8PANELS_QE; diff --git a/db/PKG_P8PANELS_QE_BASE.pck b/db/PKG_P8PANELS_QE_BASE.pck index 577e9b8..07cd11f 100644 --- a/db/PKG_P8PANELS_QE_BASE.pck +++ b/db/PKG_P8PANELS_QE_BASE.pck @@ -329,12 +329,10 @@ create or replace package PKG_P8PANELS_QE_BASE as ROPT in TOPT -- Настройка запроса ); - /* Запись SQL-выражения запроса */ - procedure QUERY_QRY_SET + /* Обновление SQL-выражения запроса */ + procedure QUERY_QRY_REFRESH ( - NRN in number, -- Рег. номер запроса - CQRY in clob, -- SQL-выражение - CQRY_MSG in clob -- Сообщение при формировании SQL-выражения (предупреждения и ошибки формирования) + NRN in number -- Рег. номер запроса ); /* Формирование SQL запроса */ @@ -2706,6 +2704,21 @@ create or replace package body PKG_P8PANELS_QE_BASE as QUERY_CH_DATE_SYNC(NRN => NRN); end QUERY_QRY_SET; + /* Обновление SQL-выражения запроса */ + procedure QUERY_QRY_REFRESH + ( + NRN in number -- Рег. номер запроса + ) + is + SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса + SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения + begin + /* Сформируем SQL-выражение */ + QUERY_SQL_BUILD(NRN => NRN, SQRY => SQRY, SQRY_MSG => SQRY_MSG); + /* Обновим его в запросе */ + QUERY_QRY_SET(NRN => NRN, CQRY => SQRY, CQRY_MSG => SQRY_MSG); + end QUERY_QRY_REFRESH; + /* Формирование SQL запроса */ procedure QUERY_SQL_BUILD ( @@ -2720,7 +2733,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as ROPT TOPT; -- Настройка запроса /* Кумулятивная установка сообщения формирования запроса */ - procedure SET_MSG + procedure ADD_QRY_MSG ( SMESSAGE in varchar2, -- Текст сообщения BCLEAR_QRY in boolean := true -- Флаг очистки сформированного запроса @@ -2735,7 +2748,37 @@ create or replace package body PKG_P8PANELS_QE_BASE as else SQRY_MSG := SQRY_MSG || CHR(10) || CHR(13) || SMESSAGE; end if; - end SET_MSG; + end ADD_QRY_MSG; + + /* Проверка соответствия условий запроса набору его аргументов */ + procedure CHECK_COND_ARGS + ( + ROPT TOPT -- Настройка запроса + ) + is + RCOND_VARS PKG_CONTVARLOC.TCONTAINER; -- Коллекция переменных условия запроса + SCOND_VAR PKG_STD.TSTRING; -- Текущая переменная условия запроса + begin + /* Извлечен переменные из условия запроса */ + RCOND_VARS := PKG_SQL_BUILD.VAR_LIST(SSQL => ROPT.SCOND); + /* Если переменные в условии есть */ + if (PKG_CONTVARLOC.COUNT_(RCONTAINER => RCOND_VARS) > 0) then + /* Обходим их */ + SCOND_VAR := PKG_CONTVARLOC.FIRST_(RCONTAINER => RCOND_VARS); + while (SCOND_VAR is not null) + loop + /* Проверяем вхождение текущей переменной в состав аргументов запроса */ + if (TARGS_INDEX_BY_NAME(RARGS => ROPT.RARGS, SNAME => SCOND_VAR) is null) then + /* В аргументах такой нет - добавляем предупреждение */ + ADD_QRY_MSG(SMESSAGE => 'Переменная условия запроса "' || SCOND_VAR || + '" отсутствует в составе его аргументов.', + BCLEAR_QRY => false); + end if; + /* Ищем следующу */ + SCOND_VAR := PKG_CONTVARLOC.NEXT_(RCONTAINER => RCOND_VARS, SNAME => SCOND_VAR); + end loop; + end if; + end CHECK_COND_ARGS; /* Поиск корневой (не имеет связей по выходу - т.е. нигде не является источником) сущности запроса */ procedure FIND_ROOT_ENT @@ -2898,7 +2941,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as end if; else /* Корневую сущность не нашли */ - SET_MSG(SMESSAGE => SMESSAGE, BCLEAR_QRY => false); + ADD_QRY_MSG(SMESSAGE => SMESSAGE, BCLEAR_QRY => false); end if; end BUILD_FROM; @@ -2916,12 +2959,14 @@ create or replace package body PKG_P8PANELS_QE_BASE as end BUILD_WHERE; begin /* - TODO: owner="root" created="10.09.2025" - text="Предусмотреть отладочные значения для аргументов запроса" + TODO: owner="root" created="13.10.2025" + text="Контроль имен аргументов запроса: только латинские и фифры и подчеркивание, начинать только с буквы. + Принудительный APPERCASE + Контроль уникальности имени аргумента" */ /* - TODO: owner="root" created="11.09.2025" - text="Проверять соответствие условий отбора запроса набору его аргументов" + TODO: owner="root" created="10.09.2025" + text="Предусмотреть отладочные значения для аргументов запроса" */ /* Читаем описание запроса */ RQ := QUERY_GET(NRN => NRN); @@ -2929,18 +2974,20 @@ create or replace package body PKG_P8PANELS_QE_BASE as RENTS := QUERY_ENTS_GET(CENTS => RQ.ENTS); /* Нет сущностей - нет запроса */ if ((RENTS is null) or (RENTS.COUNT = 0)) then - SET_MSG(SMESSAGE => 'В запросе нет сущностей.'); + ADD_QRY_MSG(SMESSAGE => 'В запросе нет сущностей.'); return; end if; /* Читаем связи запроса */ RRLS := QUERY_RLS_GET(CRLS => RQ.RLS); /* Нельзя построить запрос, если есть несвязанные сущности */ if ((RENTS.COUNT > 1) and ((RRLS is null) or (RENTS.COUNT - 1 > RRLS.COUNT))) then - SET_MSG(SMESSAGE => 'В запросе есть несвязанные сущности.'); + ADD_QRY_MSG(SMESSAGE => 'В запросе есть несвязанные сущности.'); return; end if; /* Читаем настройку запроса */ ROPT := QUERY_OPT_GET(COPT => RQ.OPT); + /* Проверяем параметры запроса */ + CHECK_COND_ARGS(ROPT => ROPT); /* Добавляем подсказку совместимости */ SQRY := PKG_SQL_BUILD.COMPATIBLE(SSQL => SQRY); /* Собираем запрос - поля */ @@ -2952,8 +2999,8 @@ create or replace package body PKG_P8PANELS_QE_BASE as exception when others then PKG_STATE.DIAGNOSTICS_STACKED(); - SET_MSG(SMESSAGE => PKG_STATE.SQL_ERRM(), BCLEAR_QRY => false); + ADD_QRY_MSG(SMESSAGE => PKG_STATE.SQL_ERRM(), BCLEAR_QRY => false); end QUERY_SQL_BUILD; - + end PKG_P8PANELS_QE_BASE; /