Как выбрать выходные параметры хранимой процедуры в виде таблицы в разработчике oracle sql

у меня есть процедура

create or replace PROCEDURE proc
(
  p1 IN varchar2,
  p2 IN varchar2,
  p3 OUT varchar2
) AS
BEGIN
 p3:= p1 || ' ' || p2
END proc

я называю это по

Declare
  P3 varchar(50);
Begin
 proc('foo', 'bar', P3)
END;

Я могу распечатать значение P3, используя

Dbms_Output.Put_line('P3: ' || P3)

Но мне нужно получить результат в виде таблицы, из которой я могу выбрать. Лучший способ, о котором я могу думать, это

Declare
  P3 varchar(50);
Begin
 proc('foo', 'bar', P3)
END;
SELECT &&P3 from dual;

Но это дает мне ошибку

Error report -
ORA-06550: line 5, column 12:
PL/SQL: ORA-00936: missing expression
ORA-06550: line 5, column 5:
PL/SQL: SQL statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilatiopn error.
*Action:

Есть ли способ выбрать значение параметра как значение столбца/строки?

Мне нужно, чтобы все это было сделано внутри одного SQL-запроса, потому что мне нужно выполнить его с другого сервера через связанный сервер.

У меня нет разрешения на создание каких-либо других хранимых процедур, функций или таблиц в базе данных.


person Tomas    schedule 10.02.2021    source источник


Ответы (2)


На мой взгляд, самый простой вариант — создать функцию, которая должна возвращать значение:

create or replace function proc (p1 IN varchar2, p2 IN varchar2)
  return varchar2
AS
BEGIN
  return p1 || ' ' || p2;
END proc;

Тогда вы бы назвали это, например.

select proc('a', 'b') from dual;

Говоря, что у вас нет разрешения на создание ... функций - ну, если вам разрешено создавать ПРОЦЕДУРУ, то вам также разрешено создавать ФУНКЦИЮ. Это такая же привилегия.


Если вы можете использовать только уже созданные процедуры, то:

SQL> create or replace PROCEDURE proc
  2  (
  3    p1 IN varchar2,
  4    p2 IN varchar2,
  5    p3 OUT varchar2
  6  ) AS
  7  BEGIN
  8    p3:= p1 || ' ' || p2;
  9  END ;
 10  /

Procedure created.

SQL> var result varchar2(20)
SQL>
SQL> exec proc('a', 'b', :result);

PL/SQL procedure successfully completed.

SQL> print :result

RESULT
--------------------------------
a b
    
SQL> select :result from dual;

:RESULT
--------------------------------
a b

SQL>
person Littlefoot    schedule 10.02.2021
comment
Как я уже сказал, у меня нет разрешения создавать или изменять какие-либо хранимые процедуры или функции. Функция создана владельцем сервера, и все, что у меня есть, это вход в систему с разрешением select. - person Tomas; 10.02.2021
comment
Ага; поэтому вы можете использовать только то, что уже создано. OK; Я добавил еще немного кода в ответ, посмотрите. - person Littlefoot; 10.02.2021
comment
Если я добавлю select :result from dual;, он попросит меня ввести привязки для result, а затем просто выберет значение, которое я ввожу, вместо значения, которое возвращает процедура. - person Tomas; 10.02.2021
comment
Отключите эту функцию в используемом вами инструменте (для этой конкретной задачи). Повторно включите его позже. - person Littlefoot; 10.02.2021
comment
Вы случайно не знаете, как это сделать? Я использую разработчик oracle sql 20.4.0.379.2205 x64. - person Tomas; 10.02.2021
comment
В SQL Developer выберите (закрасьте его синим цветом) оператор SELECT и запустите его как скрипт (сочетание клавиш F5). - person Littlefoot; 10.02.2021
comment
Что ж, это работает. Но это дает мне результат в виде вывода скрипта, а не результата запроса, и я все равно не смогу выбрать его через свой связанный сервер. - person Tomas; 10.02.2021
comment
Можете ли вы тогда перейти на SQL*Plus? Я не знаю, что еще делать в SQL Developer, поскольку вы весьма ограничены имеющимися у вас привилегиями. - person Littlefoot; 10.02.2021
comment
Хорошо, в SQL * Plus ваше решение работает отлично. Спасибо за всю вашу помощь и все время, которое вы потратили на этот вопрос. Я совершенно новичок в оракуле. - person Tomas; 10.02.2021

Если вы используете Oracle 12c и более поздних версий, вы можете использовать WITH FUNCTION. функция добавлена ​​в эту версию. С его помощью вы можете обернуть свою процедуру в блок PL/SQL локально определенной функции и использовать эту функцию в пределах SELECT. Для этого не требуется CREATE PROCEDURE.

create procedure proc (
  p1 in int,
  p2 in int,
  pout out int
)
as
begin
  pout := p1 + p2;
end;
/
with function f(
  p1 in int,
  p2 in int
) return int
as
  pout int;
begin
  proc(p1, p2, pout);
  return (pout);
end;

select f(1,2)
from dual
| F(1,2) |
| -----: |
|      3 |

db‹›fiddle здесь

person astentx    schedule 11.02.2021
comment
Это действительно делает именно то, что мне нужно. Спасибо. - person Tomas; 12.02.2021