如何返回点状结果并在动态表上使用动态游标

时间:2019-06-27 21:27:01

标签: oracle plsql

我将创建一个动态表,并在该表上使用光标,然后返回流水线结果以选择结果,但是我遇到了问题。 他不认识我的新桌子

如果我在执行包中的功能之前创建了一个表,并且不立即执行所创建的表,但我不想使用永久表,而只想使用一个临时表,则可以正常工作。

我的问题在哪里?

按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 :(得分:0)

简单来说,不要这样。在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过程中删除)并即时创建。可以认为它是 normal 表。

现在,有了表,您就不必动态地做任何事情(不扩展,难以维护,无法轻易发现错误……如果可以,请避免)。阅读您的代码,我会说您可以做到。另外,您将避免当前遇到的问题(该表尚不存在)。

最后一句话:过程test5不必为autonomous,并且您不必在commit之后drop,因为DROP是DDL,它将在执行命令之前和之后隐式提交。但是,由于您将不再需要该过程,因此在此情况下无关紧要,但请记住。