Хранимая процедура Oracle объединяет результаты - PullRequest
0 голосов
/ 02 октября 2018

Привет! Я ищу помощь в хранимых процедурах Oracle.Пожалуйста, найдите приведенный ниже Pl Sql Code.

Procedure myProc(idParam IN Number, RESULT OUT SYS_REFCURSOR)
IS
BEGIN
    FOR myMetaData in (select status, idData from Table1 where id=idParam)
    LOOP
        IF myMetaData.status='test1'
           SELECT column1, column2, column3 from Table2 where cond1=cond2;
        ELSE
           SELECT column1, column2, column3 from Table2 where column4=  
            (select column4 from.....);
        END IF; 
    END LOOP;
END myProc;

Предполагая, что выше мой код, теперь мне нужно возвращать объединенные результаты как из оператора выбора предложения IF, так и из предложения Else.Я пытался с dbms_sql.return_result ();но это не поможет.

Подскажите, пожалуйста, как объединить оба набора результатов и вернуть значение?

1 Ответ

0 голосов
/ 02 октября 2018

Есть много способов удовлетворить ваши требования, однако я бы предпочел использовать table для выполнения ваших требований.См. Ниже:

- Создайте таблицу для хранения вашего результата, если предложение if

Create table Rslt (col1 number,col2 number, col3 number);
/

- Используйте sysrefcursor, чтобы получить окончательный результат из таблицы

Procedure myProc(idParam IN Number, RESULT OUT SYS_REFCURSOR)
IS
BEGIN
    FOR myMetaData in (select status, idData from Table1 where id=idParam)
    LOOP
        IF myMetaData.status='test1'
          insert into rslt SELECT column1, column2, column3 from Table2 where cond1=cond2;
        ELSE
          insert into rslt SELECT column1, column2, column3 from Table2 where column4=  
            (select column4 from.....);
        END IF; 
    END LOOP;

    Open result for select * from rslt;

END myProc;

Другим приложением может быть объектно-ориентированное использование объекта, имеющего столбцы таблицы.См. Ниже:

Create type rslt is object
                  (col1 number,
                   col2 number, 
                   col3 number
                  );

Create type var_rslt is table of rslt ;

Procedure myProc(idParam IN Number, V_RESULT OUT SYS_REFCURSOR)
IS

v_rslt1  var_rslt:=var_rslt();
v_rslt2  var_rslt:=var_rslt();
v_rslt3  var_rslt:=var_rslt();
v_rslt4  var_rslt:=var_rslt();

BEGIN
    FOR myMetaData in (select status, idData from Table1 where id=idParam)
    LOOP
        IF myMetaData.status='test1'
          SELECT rslt(column1, column2, column3) bulk collect into v_rslt1 from Table2 where cond1=cond2;

          v_rslt2:=v_rslt2 Multiset union all v_rslt1;

        ELSE
          SELECT rslt(column1, column2, column3) bulk collect into v_rslt13 from Table2 where column4= (select column4 from.....);
          v_rslt4:=v_rslt4 multiset union all v_rslt13;

        END IF; 
    END LOOP;

    v_rslt2 := v_rslt2 multiset union all v_rslt4; 

    OPEN V_RESULT FOR SELECT * FROM table( v_rslt2 );    

END myProc;

Демонстрация:

Подготовка таблицы:

Create table Table1 (id number, status varchar2(10));
/

Insert into table1 values(1,'test1');
Insert into table1 values(2,'test2');

Create table Table2 (id number,column1 number, column2 number, column3 number);
/
insert into table2 values(1,10,20,30);
insert into table2 values(1,70,60,50);
insert into table2 values(1,20,40,30);
insert into table2 values(2,80,40,20);
insert into table2 values(2,60,20,10);


Create type rslt is object
                  (col1 number,
                   col2 number, 
                   col3 number
                  );

Create type var_rslt is table of rslt ;

Процедура:

CREATE OR REPLACE Procedure myProc(idParam IN Number, V_RESULT OUT sys_refcursor)
IS

v_rslt1  var_rslt:=var_rslt();
v_rslt2  var_rslt:=var_rslt();
v_rslt3  var_rslt:=var_rslt();
v_rslt4  var_rslt:=var_rslt();

BEGIN
    FOR myMetaData in (select status, id from Table1)
    LOOP
        IF myMetaData.status='test1' then
          SELECT rslt(column1, column2, column3) bulk collect into v_rslt1 from Table2 where id=myMetaData.id;

          v_rslt2:=v_rslt2 Multiset union all v_rslt1;

        ELSE
          SELECT rslt(column1, column2, column3) bulk collect into v_rslt3 from Table2 where id=myMetaData.id;

         v_rslt4:=v_rslt4 multiset union all v_rslt3;

        END IF; 
    END LOOP;

     v_rslt4 := v_rslt4 multiset union all v_rslt2;      

     open V_RESULT for Select * from table(v_rslt4);

END myProc;

Выполнение:

DECLARE
  var sys_refcursor;
  var1 NUMBER;
  var2 NUMBER;
  var3 NUMBER;
BEGIN
  myProc(1, var);
  LOOP
    FETCH var INTO var1,var2,var3;
    EXIT  WHEN var%notfound;
    dbms_output.put_line(var1);
  END LOOP;
END;

ВЫХОД:

SQL> /
anonymous block completed

80
60
10
70
20

Примечание. Это решение будет работать на Oracle 11g и последующих версиях .Если вы работаете с более низкой версией Oracle, вам нужно изменить определение объекта следующим образом:

Create  type rslt is object
                  (col1 number,
                   col2 number, 
                   col3 number,                   
                   map member function mem return number);

Это связано с ошибкой в ​​ Oracle 10g при использовании MULTISETоператор.

Подробнее об ошибке на http://raajeshwaran.blogspot.com/2010/07/pls-00801-internal-error-assert-at-file.html

...