diff --git a/app/panels/query_editor/components/inspector/inspector.js b/app/panels/query_editor/components/inspector/inspector.js index 04932c2..f2e6f82 100644 --- a/app/panels/query_editor/components/inspector/inspector.js +++ b/app/panels/query_editor/components/inspector/inspector.js @@ -34,6 +34,7 @@ const Inspector = ({ cond = null, substArgsVals = 0, qry = "", + qryBnd = "", qryMsg = "", onOptionsChanged = null }) => { @@ -55,7 +56,7 @@ const Inspector = ({ )} - + ); }; @@ -70,6 +71,7 @@ Inspector.propTypes = { cond: PropTypes.string, substArgsVals: PropTypes.number, qry: PropTypes.string, + qryBnd: PropTypes.string, qryMsg: PropTypes.string, onOptionsChanged: PropTypes.func }; diff --git a/app/panels/query_editor/components/inspector_query_area/inspector_query_area.js b/app/panels/query_editor/components/inspector_query_area/inspector_query_area.js index eeaa004..1a22f57 100644 --- a/app/panels/query_editor/components/inspector_query_area/inspector_query_area.js +++ b/app/panels/query_editor/components/inspector_query_area/inspector_query_area.js @@ -7,7 +7,7 @@ //Подключение библиотек //--------------------- -import React, { useState } from "react"; //Классы React +import React, { useState, useEffect } from "react"; //Классы React import PropTypes from "prop-types"; //Контроль свойств компонента import { Fab, Icon, Drawer, IconButton, TextField, Stack, Box, Snackbar, Alert } from "@mui/material"; //Компоненты MUI import { BUTTONS } from "../../../../../app.text"; //Общие текстовые ресурсы приложения @@ -40,7 +40,10 @@ const SNACK_BAR_MESSAGE_INIT = { text: null, type: null }; //----------- //Область SQL-выражения -const InspectorQueryArea = ({ query, substArgsVals = 0, qry = "", qryMsg = "", onOptionsChanged }) => { +const InspectorQueryArea = ({ query, substArgsVals = 0, qry = "", qryBnd = "", qryMsg = "" }) => { + //Собственное состояние - отображение запроса с подстановками + const [showQryBnd, setShowQryBnd] = useState(substArgsVals); + //Собственное состояние - текст всплывающего сообщения const [snackBarMessage, setSnackBarMessage] = useState(SNACK_BAR_MESSAGE_INIT); @@ -53,13 +56,10 @@ const InspectorQueryArea = ({ query, substArgsVals = 0, qry = "", qryMsg = "", o //Работа с SQL-выражением const { toggleSubstArgsVals } = useQuerySQLExpr(query); - //Уведомление родителя об изменении свойств - const notifyOptionsChanged = () => onOptionsChanged && onOptionsChanged(); - //При нажатии на кнопку отображения/сокрытия значений аргументов в SQL-выражении запроса const handleToggleSubstArgsValsClick = async () => { await toggleSubstArgsVals(); - notifyOptionsChanged(); + setShowQryBnd(showQryBnd === 1 ? 0 : 1); }; //При нажатии на кнопку копирования текста запроса @@ -87,6 +87,13 @@ const InspectorQueryArea = ({ query, substArgsVals = 0, qry = "", qryMsg = "", o //Расчет размеров тектовых полей const [qryRows, qryMsgRows] = expanded ? [15, 6] : [5, 3]; + //Расчет параметров отображения запроса + const [dispQry, qryViewTitle, qryViewIcon] = + showQryBnd === 0 ? [qry, "Отобразить значения аргументов", "code"] : [qryBnd, "Скрыть значения аргументов", "code_off"]; + + //При изменении состояние отображения подстановок в запросе + useEffect(() => setShowQryBnd(substArgsVals), [substArgsVals]); + //Генерация содержимого return ( <> @@ -101,11 +108,8 @@ const InspectorQueryArea = ({ query, substArgsVals = 0, qry = "", qryMsg = "", o {qry && ( <> - - {substArgsVals === 1 ? "code_off" : "code"} + + {qryViewIcon} content_copy @@ -120,12 +124,12 @@ const InspectorQueryArea = ({ query, substArgsVals = 0, qry = "", qryMsg = "", o - {qry && ( + {dispQry && ( { cond: data?.XOPT?.XCOND || null, substArgsVals: data?.XOPT?.XSUBST_ARGS_VALS || 0 }); - setQuerySQL({ qry: data?.XQRY, qryMsg: data?.XQRY_MSG }); + setQuerySQL({ qry: data?.XQRY, qryBnd: data?.XQRY_BND, qryMsg: data?.XQRY_MSG }); setInit(true); } finally { setRefresh(false); diff --git a/db/P8PNL_QE_QUERY.sql b/db/P8PNL_QE_QUERY.sql index 8f4b204..001198e 100644 --- a/db/P8PNL_QE_QUERY.sql +++ b/db/P8PNL_QE_QUERY.sql @@ -15,6 +15,7 @@ create table P8PNL_QE_QUERY ENTS clob, -- Сущности запроса RLS clob, -- Отношения сущностей запроса QRY clob, -- Запрос (SQL выражение) + QRY_BND 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), diff --git a/db/PKG_P8PANELS_QE_BASE.pck b/db/PKG_P8PANELS_QE_BASE.pck index c1b5e10..123d569 100644 --- a/db/PKG_P8PANELS_QE_BASE.pck +++ b/db/PKG_P8PANELS_QE_BASE.pck @@ -341,6 +341,7 @@ create or replace package PKG_P8PANELS_QE_BASE as ( NRN in number, -- Рег. номер запроса SQRY out varchar2, -- SQL-выражение + SQRY_BND out varchar2, -- SQL-выражение с подставленными значениями аргументов SQRY_MSG out varchar2 -- Сообщение при формировании SQL-выражения (предупреждения и ошибки формирования) ); @@ -368,6 +369,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as STAG_COND constant PKG_STD.TSTRING := 'XCOND'; -- Условия запроса STAG_SUBST_ARGS_VALS constant PKG_STD.TSTRING := 'XSUBST_ARGS_VALS'; -- Флаг подстановки значений аргументов в запрос STAG_QRY constant PKG_STD.TSTRING := 'XQRY'; -- SQL-выражение запроса + STAG_QRY_BND constant PKG_STD.TSTRING := 'XQRY_BND'; -- SQL-выражение запроса с подстановками STAG_QRY_MSG constant PKG_STD.TSTRING := 'XQRY_MSG'; -- Сообщение при формировании запроса /* Константы - Атрибуты для сериализации */ @@ -2341,6 +2343,8 @@ create or replace package body PKG_P8PANELS_QE_BASE as end if; /* SQL-выражение */ PKG_XFAST.HERB(SNAME => STAG_QRY, LCVALUE => RQ.QRY); + /* SQL-выражение с подстановками */ + PKG_XFAST.HERB(SNAME => STAG_QRY_BND, LCVALUE => RQ.QRY_BND); /* Сообщение при формировании SQL-выражения */ PKG_XFAST.HERB(SNAME => STAG_QRY_MSG, LCVALUE => RQ.QRY_MSG); /* Закрываем корень */ @@ -2696,6 +2700,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as ( NRN in number, -- Рег. номер запроса CQRY in clob, -- SQL-выражение + CQRY_BND in clob, -- SQL-выражение с подставленными значениями аргументов CQRY_MSG in clob -- Сообщение при формировании SQL-выражения (предупреждения и ошибки формирования) ) is @@ -2703,6 +2708,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as /* Сохраним её */ update P8PNL_QE_QUERY T set T.QRY = CQRY, + T.QRY_BND = CQRY_BND, T.QRY_MSG = CQRY_MSG where T.RN = NRN; /* Контроль изменения данных */ @@ -2720,12 +2726,13 @@ create or replace package body PKG_P8PANELS_QE_BASE as ) is SQRY PKG_STD.TLSTRING; -- SQL-выражение запроса + SQRY_BND PKG_STD.TLSTRING; -- SQL-выражение запроса с подстановками SQRY_MSG PKG_STD.TLSTRING; -- Сообщение при формировании SQL-выражения begin /* Сформируем SQL-выражение */ - QUERY_SQL_BUILD(NRN => NRN, SQRY => SQRY, SQRY_MSG => SQRY_MSG); + QUERY_SQL_BUILD(NRN => NRN, SQRY => SQRY, SQRY_BND => SQRY_BND, SQRY_MSG => SQRY_MSG); /* Обновим его в запросе */ - QUERY_QRY_SET(NRN => NRN, CQRY => SQRY, CQRY_MSG => SQRY_MSG); + QUERY_QRY_SET(NRN => NRN, CQRY => SQRY, CQRY_BND => SQRY_BND, CQRY_MSG => SQRY_MSG); end QUERY_QRY_REFRESH; /* Формирование SQL запроса */ @@ -2733,6 +2740,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as ( NRN in number, -- Рег. номер запроса SQRY out varchar2, -- SQL-выражение + SQRY_BND out varchar2, -- SQL-выражение с подставленными значениями аргументов SQRY_MSG out varchar2 -- Сообщение при формировании SQL-выражения (предупреждения и ошибки формирования) ) is @@ -2750,7 +2758,8 @@ create or replace package body PKG_P8PANELS_QE_BASE as is begin if (BCLEAR_QRY) then - SQRY := null; + SQRY := null; + SQRY_BND := null; end if; if (SQRY_MSG is null) then SQRY_MSG := SMESSAGE; @@ -2964,28 +2973,40 @@ create or replace package body PKG_P8PANELS_QE_BASE as begin if (ROPT.SCOND is not null) then PKG_SQL_BUILD.APPEND(SSQL => SQRY, SELEMENT1 => 'where ' || ROPT.SCOND); - end if; - if ((ROPT.NSUBST_ARGS_VALS = 1) and (ROPT.RARGS is not null) and (ROPT.RARGS.COUNT > 0)) then + end if; + end BUILD_WHERE; + + /* Подстановка отладочных значений в SQL-выражение */ + procedure BOUND + ( + ROPT TOPT, -- Настройка запроса + SQRY in varchar2, -- Сформированное SQL-выражение + SQRY_BND out varchar2 -- SQL-выражение с подстановками + ) + is + begin + SQRY_BND := SQRY; + if ((ROPT.RARGS is not null) and (ROPT.RARGS.COUNT > 0)) then for I in ROPT.RARGS.FIRST .. ROPT.RARGS.LAST loop begin case when ROPT.RARGS(I).NDATA_TYPE = PKG_STD.DATA_TYPE_STR then - SQRY := PKG_SQL_BUILD.VAR_REPLACE_TO_STR(SSQL => SQRY, - SNAME => ROPT.RARGS(I).SNAME, - SVALUE => ROPT.RARGS(I).SVALUE); + SQRY_BND := PKG_SQL_BUILD.VAR_REPLACE_TO_STR(SSQL => SQRY_BND, + SNAME => ROPT.RARGS(I).SNAME, + SVALUE => ROPT.RARGS(I).SVALUE); when ROPT.RARGS(I).NDATA_TYPE = PKG_STD.DATA_TYPE_NUM then - SQRY := PKG_SQL_BUILD.VAR_REPLACE_TO_NUM(SSQL => SQRY, - SNAME => ROPT.RARGS(I).SNAME, - NVALUE => TO_NUMBER(ROPT.RARGS(I).SVALUE)); + SQRY_BND := PKG_SQL_BUILD.VAR_REPLACE_TO_NUM(SSQL => SQRY_BND, + SNAME => ROPT.RARGS(I).SNAME, + NVALUE => TO_NUMBER(ROPT.RARGS(I).SVALUE)); when ROPT.RARGS(I).NDATA_TYPE = PKG_STD.DATA_TYPE_DATE then - SQRY := PKG_SQL_BUILD.VAR_REPLACE_TO_DATE(SSQL => SQRY, - SNAME => ROPT.RARGS(I).SNAME, - DVALUE => TO_DATE(ROPT.RARGS(I).SVALUE, 'yyyy-mm-dd')); + SQRY_BND := PKG_SQL_BUILD.VAR_REPLACE_TO_DATE(SSQL => SQRY_BND, + SNAME => ROPT.RARGS(I).SNAME, + DVALUE => TO_DATE(ROPT.RARGS(I).SVALUE, 'yyyy-mm-dd')); else - SQRY := PKG_SQL_BUILD.VAR_REPLACE_TO_ANY(SSQL => SQRY, - SNAME => ROPT.RARGS(I).SNAME, - SANY => ROPT.RARGS(I).SVALUE); + SQRY_BND := PKG_SQL_BUILD.VAR_REPLACE_TO_ANY(SSQL => SQRY_BND, + SNAME => ROPT.RARGS(I).SNAME, + SANY => ROPT.RARGS(I).SVALUE); end case; exception when others then @@ -2995,7 +3016,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as end; end loop; end if; - end BUILD_WHERE; + end BOUND; begin /* Читаем описание запроса */ RQ := QUERY_GET(NRN => NRN); @@ -3025,6 +3046,8 @@ create or replace package body PKG_P8PANELS_QE_BASE as BUILD_FROM(RENTS => RENTS, RRLS => RRLS, SQRY => SQRY); /* Собираем запрос - условия */ BUILD_WHERE(ROPT => ROPT, SQRY => SQRY); + /* Сделаем подстановки */ + BOUND(ROPT => ROPT, SQRY => SQRY, SQRY_BND => SQRY_BND); exception when others then PKG_STATE.DIAGNOSTICS_STACKED();