Это зависит от того, что может обработать ваше приложение. У вас может быть функция-обертка, которая возвращает курсор ref:
create or replace function impl_xerox_printer_check_wrap (
printer_id in varchar2
)
return sys_refcursor as
o_status varchar2(200);
o_message varchar2(200);
o_refcursor sys_refcursor;
begin
impl_xerox_printer_check(printer_id => printer_id, o_status => o_status, o_message => o_message);
open o_refcursor for select o_status as status, o_message as message from dual;
return o_refcursor;
end;
/
select impl_xerox_printer_check_wrap('551555115') from dual;
IMPL_XEROX_PRINTER_C
--------------------
CURSOR STATEMENT : 1
CURSOR STATEMENT : 1
STATUS MESSAGE
---------- ------------------------------
TRUE ALL IS GOOD
(вывод, как показано SQL Developer, запускается как скрипт). Но ваше приложение может не знать, что с этим делать.
Вы можете использовать коллекцию или тип объекта, но если вы не определите свой собственный на уровне схемы, интерпретировать это будет немного сложно:
create or replace function impl_xerox_printer_check_wrap (
printer_id in varchar2
)
return sys.odcivarchar2list as
o_result sys.odcivarchar2list;
begin
o_result := new sys.odcivarchar2list();
o_result.extend(2);
impl_xerox_printer_check(printer_id => printer_id, o_status => o_result(1), o_message => o_result(2));
return o_result;
end;
/
select * from table (impl_xerox_printer_check_wrap('551555115'));
Result Sequence
------------------------------------------------
TRUE
ALL IS GOOD
Или вы можете go через XML, что звучит странно, но дает хороший результат:
create or replace function impl_xerox_printer_check_wrap (
printer_id in varchar2
)
return xmltype as
o_status varchar2(200);
o_message varchar2(200);
o_refcursor sys_refcursor;
begin
impl_xerox_printer_check(printer_id => printer_id, o_status => o_status, o_message => o_message);
open o_refcursor for select o_status as status, o_message as message from dual;
return xmltype(o_refcursor);
end;
/
select impl_xerox_printer_check_wrap('551555115') from dual;
IMPL_XEROX_PRINTER_CHECK_WRAP('551555115')
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<ROWSET>
<ROW>
<STATUS>FALSE</STATUS>
<MESSAGE>SOMTHING WENT WRONG!!! </MESSAGE>
</ROW>
</ROWSET>
ОК, это не выглядит очень полезным ... но затем вы извлекаете значения :
select status, message
from xmltable(
'/ROWSET/ROW'
passing impl_xerox_printer_check_wrap('551555115')
columns status varchar2(200) path 'STATUS',
message varchar2(200) path 'MESSAGE'
);
STATUS MESSAGE
---------- ------------------------------
FALSE SOMTHING WENT WRONG!!!
db <> fiddle
Ваше приложение может выполнить этот запрос - конечно, передав идентификатор принтера в качестве переменной привязки - и получит простой ответ набор результатов.
Поскольку вы используете 12 c, вы можете использовать возможности PL / SQL, добавленные к факторингу подзапроса, поэтому вам вообще не нужно создавать постоянную функцию ( хотя вы все равно можете предпочесть):
drop function IMPL_XEROX_PRINTER_CHECK_WRAP;
with
function impl_xerox_printer_check_wrap (
printer_id in varchar2
)
return xmltype as
o_status varchar2(200);
o_message varchar2(200);
o_refcursor sys_refcursor;
begin
impl_xerox_printer_check(printer_id => printer_id, o_status => o_status, o_message => o_message);
open o_refcursor for select o_status as status, o_message as message from dual;
return xmltype(o_refcursor);
end;
select impl_xerox_printer_check_wrap('551555115')
from dual
/
, если вы хотите XML (согласно комментарию), или с XMLTable, если вы этого не сделаете:
IMPL_XEROX_PRINTER_CHECK_WRAP('551555115')
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<ROWSET>
<ROW>
<STATUS>TRUE</STATUS>
<MESSAGE>ALL IS GOOD</MESSAGE>
</ROW>
</ROWSET>
with
function impl_xerox_printer_check_wrap (
printer_id in varchar2
)
return xmltype as
o_status varchar2(200);
o_message varchar2(200);
o_refcursor sys_refcursor;
begin
impl_xerox_printer_check(printer_id => printer_id, o_status => o_status, o_message => o_message);
open o_refcursor for select o_status as status, o_message as message from dual;
return xmltype(o_refcursor);
end;
select status, message
from xmltable(
'/ROWSET/ROW'
passing impl_xerox_printer_check_wrap('551555115')
columns status varchar2(200) path 'STATUS',
message varchar2(200) path 'MESSAGE'
)
/
STATUS MESSAGE
---------- ------------------------------
FALSE SOMTHING WENT WRONG!!!
Дело в том, что SP вставляет некоторые данные во временную таблицу
Это довольно важный пропуск п. Вы не можете выполнить вставку или обновление в вызове функции из выбора. В документации перечислены ограничения на функции, вызываемые из SQL, а более подробно рассматривается в этом предупреждении :
Поскольку SQL является декларативным языком вместо императивного (или процедурного) вы не можете знать, сколько раз будет выполняться функция, вызванная оператором SQL, даже если функция написана на PL / SQL, императивном языке.
Если бы функции было разрешено выполнять DML, то вы не могли бы контролировать, сколько раз выполнялся DML. Например, если он выполняет вставку, он может попытаться вставить одну и ту же строку дважды и либо дублировать данные, либо получить нарушение ограничения.
Технически можно объявить функцию с помощью pragma autonomous_transaction
Как и в это модифицированный db <> fiddle , но это ужасный хак, который, вероятно, в конечном итоге вызовет больше проблем, чем решит, по причинам, указанным выше. Вы могли бы обойтись без этого, если бы вы только когда-либо делали однорядные вызовы, как в вашем примере, но даже тогда это не гарантируется; и даже если он работает сейчас, он может сломаться в будущем.