2010-11-11 3 views
4

У меня есть существующая хранимая процедура, которая принимает 2 параметра и возвращает обратно курсор oracle. Курсор содержит от 30 до 60 строк данных.как вызвать хранимую процедуру из другой хранимой процедуры в oracle

Я хочу использовать вышеуказанную ранее существующую хранимую процедуру в другой хранимой процедуре в качестве таблицы ... В основном я хочу вызвать ранее существовавшую хранимую процедуру и посмотреть, содержат ли возвращенные строки обратно определенное значение.

Например:

SP 1 = get_data_1 (returns oracle cursor) 
SP 2 = get_data_2 

в get_data_2

select count(*) from get_data_1 (pass_input_parms) A where A.ID = '12345' 

Концептуально это кажется тривиальным, что нужно сделать для меня, однако, будучи новым для оракула мире я не знаю, как использовать ранее существовавших хранимых процедур, возвращающих курсоры.

Как мне это сделать?

ответ

5

Вы не можете повторно использовать REF CURSOR из get_data_1 в следующем SQL-выражении, потому что это всего лишь указатель на дескриптор инструкции. Сам курсор не содержит данных.

Вы могли бы сделать что-то вроде

CREATE PROCEDURE get_data_2(p_cnt OUT NUMBER) 
AS 
    l_rc <<your cursor type>>; 
    l_rec <<the type your cursor returns>>; 
BEGIN 
    get_data_1(<<parameter 1>>, <<parameter 2>>, l_rc); 
    p_cnt := 0; 
    LOOP 
    FETCH l_rc INTO l_rec; 
    EXIT WHEN l_rc%NOTFOUND; 

    IF(l_rec.id = '12345') 
    THEN 
     p_cnt := p_cnt + 1; 
    END IF; 
    END LOOP; 
    CLOSE l_rc; 
END; 

Как вы можете себе представить, хотя, это имеет тенденцию стареть относительно быстро. Учитывая, что в Oracle Oracle обычно не хранит процедуры, возвращающие параметры REF CURSOR, за исключением случаев, когда вы возвращаете готовое представление данных в клиентское приложение. Например, если было общее представление, что GET_DATA_1 и GET_DATA_2 могли запрашивать, а не GET_DATA_2, вызывать GET_DATA_1, что упростило бы программу. Если GET_DATA_1 была конвейерной функцией таблицы, а не процедурой, которая возвращала REF CURSOR, тогда было бы гораздо проще вызвать GET_DATA_1 из GET_DATA_2.

Если вы хотите, чтобы начать работу с конвейерными табличными функциями (с использованием схемы SCOTT)

create or replace type emp_obj as object (
    empno number, 
    ename varchar2(10), 
    job varchar2(9), 
    mgr number, 
    hiredate date); 
/

create type emp_tbl 
as 
table of emp_obj; 
/

create function emp_pipe(p_deptno IN NUMBER) 
    return emp_tbl pipelined 
is 
begin 
    FOR x IN (SELECT * FROM emp WHERE deptno = p_deptno) 
    LOOP 
    PIPE ROW(emp_obj(x.empno, 
         x.ename, 
         x.job, 
         x.mgr, 
         x.hiredate)); 
    END LOOP; 
END; 
/

SQL> select * from table(emp_pipe(10)); 

    EMPNO ENAME  JOB    MGR HIREDATE 
---------- ---------- --------- ---------- --------- 
     7782 CLARK  MANAGER   7839 09-JUN-81 
     7839 KING  PRESIDENT   17-NOV-81 
     7934 MILLER  CLERK   7782 23-JAN-82 
+0

Спасибо, что имеет смысл. Хотя петля кажется неэффективной. Любой хороший ресурс, на который вы можете указать, показывает, что делает конвейерные функции, а затем использует их в другом SP? – Reeth

+0

@Reeth - добавлена ​​быстрая демонстрация использования конвейерных функций таблицы. –

0

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

Смежные вопросы