oracle как перехватить ошибку в sql-запросе в блоке курсора

#oracle #exception #cursor

#Oracle #исключение #курсор

Вопрос:

как я могу перехватить ошибку в sql-запросе в блоке исключения? В приведенном ниже примере (деление на ноль — выберите (5/0) в качестве примера из dual) блок исключения не выполняется.

 FUNCTION getData(p_result out integer)   
  RETURN SYS_REFCURSOR
AS
  my_cursor SYS_REFCURSOR;
BEGIN
  OPEN my_cursor FOR select (5 / 0) as example  from dual;
  
  p_result := 1;
  RETURN my_cursor;
  
exception 
    WHEN OTHERS THEN 
    p_result := 0;
END getData;
  

Ответ №1:

Вы перехватываете ошибку не в том месте. Она возникает при вызове функции, а не при ее создании. Вот пример.

Во-первых, ваша функция:

 SQL> create or replace
  2  FUNCTION getData(p_result out integer)
  3    RETURN SYS_REFCURSOR
  4  AS
  5    my_cursor SYS_REFCURSOR;
  6  BEGIN
  7    OPEN my_cursor FOR select (5 / 0) as example  from dual;
  8
  9    p_result := 1;
 10    RETURN my_cursor;
 11
 12  exception
 13      WHEN OTHERS THEN
 14      p_result := 0;
 15  END getData;
 16  /

Function created.
  

Вызываю это; Я просто показываю сообщение об ошибке; вы бы сделали что-нибудь еще.

 SQL> declare
  2    l_res  integer;
  3    rc     sys_refcursor;
  4    l_exam number;
  5  begin
  6    rc := getdata(l_res);
  7    loop
  8      fetch rc into l_exam;
  9      exit when rc%notfound;
 10      dbms_output.put_line(l_exam);
 11    end loop;
 12    close rc;
 13  exception
 14    when others then
 15      dbms_output.put_line('Error: ' || sqlerrm);
 16  end;
 17  /
Error: ORA-01476: divisor is equal to zero

PL/SQL procedure successfully completed.

SQL>
  

Комментарии:

1. Спасибо тебе, Литтлфут. Вы правы, если я вызываю эту функцию в Oracle, я получаю ошибку. Проблема в том, что я вызываю ее из PHP, а функция oci_error не возвращает ошибку.

2. Добро пожаловать. Извините, я не знаю PHP, поэтому больше ничем не могу помочь.

Ответ №2:

 -------Just User this function------
------------------------------------
FUNCTION getData(p_result out integer)   
  RETURN SYS_REFCURSOR
AS
  my_cursor SYS_REFCURSOR;
BEGIN
  OPEN my_cursor FOR select (5 / NULLIF(0,0)) as example  from dual;
  
  p_result := 1;
  RETURN my_cursor;
  
exception 
    WHEN OTHERS THEN 
    p_result := 0;
END getData;