SQL данные не найдены, исключение не выполняется - PullRequest
0 голосов
/ 02 апреля 2020

Ниже приведен код, который должен выполнять блок исключения, если в основном блоке не найдено данных. Однако блок исключения не выполняется, даже если запрос не возвращает никакой записи. Запрос соединяется с другой таблицей, и когда результат совпадает с запросом, он выбирает первую запись, в противном случае он должен присвоить нулевые значения полям и вернуть курсор в пользовательский интерфейс. Приведенное ниже значение для курсора всегда равно 0, и блок исключения не выполняется.

BEGIN
    wf_common.write_debug(vprocname, ' 111=', ts);
    OPEN cinfo FOR SELECT
                       name,
                       phone,
                       alt_phone,
                       email
                   FROM
                       abc
                   WHERE
                       id IN (
                           SELECT
                               id
                           FROM
                               xyz
                           WHERE
                               emp_no = vempno
                       )
                       AND name IS NOT NULL
                       AND ROWNUM = 1;

    wf_common.write_debug(vprocname, 'COUNT' || cinfo%rowcount, ts);
EXCEPTION
    WHEN no_data_found THEN
        wf_common.write_debug(vprocname, '222=', ts);
        OPEN cinfo FOR SELECT
                           '' name,
                           '' phone,
                           '' alt_phone,
                           '' email
                       FROM
                           dual;

        wf_common.write_debug(vprocname, 'COUNT' || cinfo%rowcount, ts);
END;

Ответы [ 2 ]

0 голосов
/ 02 апреля 2020

Это курсор . Это не поднимает no_data_found. Как вы узнаете, вернет ли он что-то или нет? Вы не будете, пока вы

  • не откроете его
  • получите его

Тогда вы узнаете.

Так что - к сожалению - сначала нужно проверить, а потом решить, что делать. Например (на основе образца схемы Скотта):

SQL> create or replace function f_test (par_deptno in emp.deptno%type)
  2    return sys_refcursor
  3  is
  4    type cinfot is record (empno emp.empno%type,
  5                           ename emp.ename%type,
  6                           job   emp.job%type);
  7    cinfor    cinfot;
  8    cinfo     sys_refcursor;
  9  begin
 10    -- in order to test whether it returns something, open & fetch
 11    open cinfo for 'select empno, ename, job
 12                    from emp
 13                    where deptno = :a' using par_deptno;
 14    fetch cinfo into cinfor;
 15
 16    -- has anything been found?
 17    if cinfo%found then
 18       -- something has been found - process it
 19       close cinfo;
 20       open cinfo for 'select empno, ename, job
 21                       from emp
 22                       where deptno = :a' using par_deptno;
 23
 24    else
 25       -- nothing has been found; open another cursor
 26       close cinfo;
 27       open cinfo for select deptno, dname, loc
 28                      from dept;
 29    end if;
 30
 31    return cinfo;
 32  end;
 33  /

Function created.

Тестирование: отдел 10 существует в EMP таблице, поэтому - вернуть ее содержимое:

SQL> select f_test(10) From dual;

F_TEST(10)
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

     EMPNO ENAME      JOB
---------- ---------- ---------
      7782 CLARK      MANAGER
      7839 KING       PRESIDENT
      7934 MILLER     CLERK

Отдел 50 так не существует - вернуть DEPT содержимое таблицы:

SQL> select f_test(50) From dual;

F_TEST(50)
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON


SQL>
0 голосов
/ 02 апреля 2020

Заменить WHEN NO_DATA_FOUND на WHEN OTHERS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...