我将创建一个动态表,并在该表上使用光标,然后返回流水线结果以选择结果,但是我遇到了问题。 他不认识我的新桌子
如果我在执行包中的功能之前创建了一个表,并且不立即执行所创建的表,但我不想使用永久表,而只想使用一个临时表,则可以正常工作。
我的问题在哪里?
按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
答案 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,它将在执行命令之前和之后隐式提交。但是,由于您将不再需要该过程,因此在此情况下无关紧要,但请记住。