Oracle - для вывода цикла - PullRequest
       1

Oracle - для вывода цикла

0 голосов
/ 06 декабря 2018

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

create or replace FUNCTION FUNC1(num_list varchar2,separator varchar2) RETURN typeAs PIPELINED 
as 
begin
FOR nums in (select regexp_substr(num_list,'[^'||separator||']+', 1, level) num from dual
  connect by regexp_substr(num_list, '[^'||separator||']+', 1, level) is not null)
loop
PIPE ROW(typeA(NVL(nums.num,0) ,NVL(FUNC2(nums.num),0)));
end loop;
end;

Отметив, что:

create or replace TYPE typeA AS OBJECT (num varchar2(20),val varchar2(20))
create or replace TYPE typeAs AS TABLE OF typeA;

функция работает правильно, если все числа в списке вернут вывод, отличный от нуля, при передаче в FUNC2.Но если число возвращает ноль при передаче в FUNC2, все последующие числа в списке не отображаются в выходных данных FUNC1.

Редактировать: Результаты:

select * from table(FUNC1('1111,4333,121212',',')) :
output:
-----------------
1111 | val1

два других числане показывается в выходных данных, поскольку FUNC2 ('4333') является нулевым, зная, что FUNC2 ('121212') имеет значение.время:

select * from table(FUNC1('1111,2222,121212',',')) :
output:
-----------------
1111     | val1
2222     | val2
121212   | val3

1 Ответ

0 голосов
/ 06 декабря 2018

Вы увидите этот эффект, если func2 выдает исключение no_data_found, а не возвращает ноль, для входного значения 4333. Это, вероятно, имеет смысл, если эта функция ищет значение из другой таблицы.

Поскольку ваш вызов func1 находится в контексте SQL, это исключение является молчаливым фатальным, и выполнение встречается, когда оно встречается, без каких-либо указаний на ошибку.Если бы вы вызвали func1 из контекста PL / SQL, вы бы увидели исключение.

В качестве демонстрации с пустышкой func2:

create or replace function func2(p_num number) return varchar2 as
begin
  if p_num = 4333 then
    raise no_data_found;
  end if;

  return case p_num
    when 1111 then 'val1'
    when 2222 then 'val2'
    when 121212 then 'val3'
    else null
  end;
end func2;
/

и вашей исходной функцией:

create or replace FUNCTION FUNC1(num_list varchar2,separator varchar2) RETURN typeAs PIPELINED 
as
  l_val varchar2(20);
begin
  FOR nums in (select regexp_substr(num_list,'[^'||separator||']+', 1, level) num from dual
    connect by regexp_substr(num_list, '[^'||separator||']+', 1, level) is not null)
  loop
    PIPE ROW(typeA(NVL(nums.num,0) ,NVL(FUNC2(nums.num),0)));
  end loop;
end;
/

select * from table(FUNC1('1111,4333,121212',','));

NUM                  VAL                 
-------------------- --------------------
1111                 val1                

select * from table(FUNC1('1111,2222,121212',','));

NUM                  VAL                 
-------------------- --------------------
1111                 val1                
2222                 val2                
121212               val3                

Вы можете изменить func1, чтобы явно вызывать функцию и обрабатывать исключение:

create or replace FUNCTION FUNC1(num_list varchar2,separator varchar2) RETURN typeAs PIPELINED 
as
  l_val varchar2(20);
begin
  FOR nums in (select regexp_substr(num_list,'[^'||separator||']+', 1, level) num from dual
    connect by regexp_substr(num_list, '[^'||separator||']+', 1, level) is not null)
  loop
    begin
      l_val := FUNC2(nums.num);
    exception
      when no_data_found then
        l_val := null;
    end;
    PIPE ROW(typeA(NVL(nums.num,0) ,NVL(l_val,0)));
  end loop;
end;
/

select * from table(FUNC1('1111,4333,121212',','));

NUM                  VAL                 
-------------------- --------------------
1111                 val1                
4333                 0                   
121212               val3                

select * from table(FUNC1('1111,2222,121212',','));

NUM                  VAL                 
-------------------- --------------------
1111                 val1                
2222                 val2                
121212               val3                

db <> fiddle demo .

Или вы можете изменить func2, чтобы он перехватывал исключение и возвращал ноль, или изменял свой запрос, чтобы он не мог получить исключение в первую очередь.Насколько это уместно, решать вам - его можно использовать в других местах, где необходимо распространить исключение ...

(Между прочим, поскольку func2 возвращает строку, nvl() для этого следуетдействительно используйте строку - даже если это 0, поскольку она неявно преобразуется в настоящее время.)

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