Как вернуть результат в виде контура и использовать динамический курсор на динамической таблице - PullRequest
0 голосов
/ 28 июня 2019

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

Это сработало, если я создаю таблицу перед выполнением функции в пакете и если я не выполняю немедленно созданную таблицу, но мне не нужна постоянная таблица, только временная таблица.

Где моя проблема?

Нажмите CTRL + F и выполните поиск - Теперь он не знает info_table, так что мне делать?

---- Так что это в моем пакете заголовка

    type data_rec is record 
      ( 
       l_util_id_source      number,  
       l_util_id_cible  number,  
       l_level         number
     ) ; 


type l_data_type is table of data_rec;

function obtenir_closeness return l_data_type pipelined ;


--And now my body

function obtenir_closeness return l_data_type pipelined 
     is 
     PRAGMA AUTONOMOUS_TRANSACTION;

    cc sys_refcursor;
    l_row lig_relation%ROWTYPE;
    sorti_type  data_rec; 

V_STRING VARCHAR2(1000) := 'DECLARE
    sorti_type  data_rec;
    BEGIN

  FOR C1 IN (SELECT * FROM info_table) LOOP
    null;

  END LOOP;

END;';

begin

test3();
test4();    

- Создать мою табличную работу.

execute immediate 'create table info_table (util_id_source varchar2(50),
util_id_cible varchar2(50),
level_connaissance number )';
commit;

- Вставьте в мою таблицу работы.

execute immediate 'insert into info_table select util_id_source,util_id_cible,1
from lig_relation
group by util_id_source,util_id_cible';
commit;

- Теперь он не знает info_table, так что мне делать?

 OPEN cc for 'select * from info_table';

     LOOP 
        FETCH cc INTO l_row; 

               EXIT WHEN CC%NOTFOUND; 
                        sorti_type.l_util_id_source := l_row.util_id_source; 
                        sorti_type.l_util_id_cible := l_row .util_id_cible; 
                        sorti_type.l_level := l_row .level_connaissance; 

  pipe row(sorti_type);
END LOOP;

  CLOSE cc; 
  test5(); 
 return; 

end obtenir_closeness ;

- это процедура 3

procedure test3
    is
    v_ctr number:=1;
    v_execute_1 varchar2(32767);

    begin
    --This is where i insert what i need and it work.
v_execute_1:= 'begin 
while :v_ctr<10
loop
FOR l_info IN(
select * from info_table where level_connaissance = :v_ctr)
loop
insert into info_table select l_info.util_id_source,util_id_cible,:v_ctr+1
from lig_relation
where util_id_source = l_info.util_id_cible
and (select count(*) from info_table where util_id_source = l_info.util_id_source  and util_id_cible = lig_relation.util_id_cible)=0
group by util_id_source,util_id_cible;
end loop;

:v_ctr := :v_ctr+1;
end loop;
end;';

execute immediate v_execute_1 using in out v_ctr;
commit;
    end test3;

- это процедура 5

procedure test5
    is
 Pragma Autonomous_transaction;
    begin
    execute immediate 'drop table info_table';
    commit;
    end test5;



END 

1 Ответ

0 голосов
/ 28 июня 2019

Просто не делай так.В Oracle мы обычно - но вы можете прочитать это как никогда - создавать таблицы динамически.Это то, что делает MS SQL Server.

Поскольку вы не хотите использовать постоянную таблицу, создайте глобальную временную таблицу (GTT) (или частную, если ваша версия Oracle поддерживает ее).Например:

SQL> create global temporary table info_table
  2    (util_id_source        varchar2(50),
  3     util_id_cible         varchar2(50),
  4     level_connaissance    number
  5    )
  6    on commit preserve rows;            --> or ON COMMIT DELETE ROWS; pick one

Table created.

SQL>

Данные, которые вы помещаете в эту таблицу, будут видны только вам и только во время сеанса (если вы решите сохранить строки при фиксации) или транзакции (если вы решите их удалить).После того, как вы выйдете из сеанса, данные будут потеряны, таблица будет пустой, она не займет никакого места.Поэтому, если вас это беспокоит, я предлагаю вам перейти на GTT.

Обратите внимание, что вы создаете таблицу только один раз и используете ее столько раз, сколько хотите. НЕ удалите его (особенно из ваших процедур PL / SQL) и создайте на лету.Думайте об этом, как будто это обычная таблица.

Теперь, когда у вас есть таблица, вам не нужно ничего делать динамически (что не масштабируется, трудноподдерживать, вы не можете легко обнаружить ошибку ... избегайте ее, если можете).Читая ваш код, я бы сказал, что вы можете это сделать.Кроме того, вы избежите проблем, которые у вас есть (таблица еще не существует).

Последнее замечание: процедура test5 не обязательно должна быть autonomous, и вы неcommit после drop необходимо, потому что DROP - это DDL, он неявно фиксируется до и после выполнения команды.Хотя, поскольку вам больше не понадобится эта процедура, она не имеет значения в этом контексте, но помните об этом.

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