ORA-01403 при ссылке на элемент страницы в PL / SQL - PullRequest
0 голосов
/ 15 января 2019

Я создаю страницу Oracle ApEx для отображения графиков данных. Данные вводятся в таблицу в качестве входных данных, но фактическая рассчитанная метрика может отличаться в зависимости от того, какой KPI просматривается (AVG (VALUE_1); SUM (VALUE_1) / SUM (VALUE_2) и т. Д.); эти расчеты хранятся в отдельной таблице. Поскольку я хочу, чтобы все было динамически для использования взаимодействий, я использую источник тела функции PL / SQL, возвращающего SQL-запрос. Вот упрощенная версия

DECLARE
    SQL_STMT      VARCHAR2 (32767);
    CALC_CLAUSE   VARCHAR2 (4000);
BEGIN
    SELECT CALCULATION
      INTO CALC_CLAUSE
      FROM KPI_TYPES
     WHERE ID = 101;

    --when the value itself is entered, the results display as intended

    SQL_STMT := 'SELECT DATE, ' || CALC_CLAUSE || ' KPI_VALUE
    FROM DATA_VALUES
    WHERE TYPE_ID = :P_KPI
    GROUP BY DATE';

    RETURN SQL_STMT;
END;

Как отмечалось выше, эта функция работает, как и ожидалось, когда идентификатор KPI вводится вручную, но я хочу, чтобы он был динамическим. У меня есть элемент списка выбора (P_KPI), чтобы пользователь мог выбрать просматриваемый KPI. Его значение фактически установлено на предыдущей странице с проверкой, поэтому оно никогда не должно быть нулевым.

Когда я обновляю условие CALC_CLAUSE:

WHERE ID = :P_KPI

Я получаю следующую ошибку:

ORA-01403: no data found

Как я могу ссылаться на этот элемент страницы в функции?

Ответы [ 2 ]

0 голосов
/ 19 апреля 2019

Начиная с сохраненной функции, предложенной Littlefoot, я смог использовать это решение:

http://vincentdeelen.blogspot.com/2014/02/interactive-report-based-on-dynamic-sql.html

У меня есть процесс страницы, который создает коллекцию со строкой динамического запроса. Область SQL диаграмм теперь запрашивает из коллекции, и я могу использовать все свои элементы страницы для соответствующей фильтрации данных.

0 голосов
/ 15 января 2019

Код, который вы опубликовали, недействителен (не компилируется), а приведенное вами объяснение неверно. Хотя это упрощенная версия , я бы предпочел, чтобы вы опубликовали точную информацию.

Вы сказали, что оператор SQL равен

SELECT DATE, '||CALC_CLAUSE||' KPI_VALUE
FROM DATA_VALUES ...

пока CALC_CLAUSE выглядит как

WHERE ID = :P_KPI

так что весь запрос выглядит как

SELECT DATE, WHERE ID = :P_KPI KPI_VALUE
FROM DATA_VALUES ...

что просто не имеет смысла. Что это за CALC_CLAUSE, в конце концов? Разве это не должно быть AVG(VALUE_1) или что-то в этом роде?


По состоянию на :P_KPI элемент, значение которого выглядит как NULL: не имеет значения, что вы видите его на экране - он должен находиться в состоянии сеанса . Самый простой способ сделать это - отправить страницу, так что вы сделали это?

Попробуйте создать хранимую функцию (в базе данных, а не в Apex) и передать ей значение P_KPI в качестве параметра. Затем проверьте, что вы получаете, а также результат. При работе с динамическим SQL хорошей идеей будет DBMS_OUTPUT.PUT_LINE результирующий оператор (в вашем примере это будет SQL_STMT), скопировать / вставить его в SQL * Plus (или любой другой инструмент, который вы используете, например, SQL Developer). ) и посмотрите, правильно ли это работает.

Например:

CREATE OR REPLACE FUNCTION f_stmt (par_kpi IN NUMBER)
   RETURN VARCHAR2
IS
   sql_stmt      VARCHAR2 (32767);
   calc_clause   VARCHAR2 (4000);
BEGIN
   SELECT calculation
     INTO calc_clause
     FROM kpi_types
    WHERE id = par_kpi;

   sql_stmt :=
         'SELECT DATE, '
      || calc_clause
      || ' KPI_VALUE '
      || ' FROM DATA_VALUES '
      || ' WHERE TYPE_ID = '
      || par_kpi
      || ' GROUP BY DATE';

   DBMS_OUTPUT.put_line (sql_stmt);

   RETURN sql_stmt;
END;
...