包中使用ID更新的嵌套表

问题描述 投票:1回答:1

我正在研究Oracle 12c EE。我正在创建一个包含一些过程的程序包。其中一个使用集合来更新数据。我在数据库中创建了一个对象类型:

CREATE OR REPLACE TYPE type_record IS OBJECT(
    column1        NUMBER,
    column2        NUMBER,
    column3        NUMBER);

CREATE OR REPLACE TYPE type_table IS TABLE OF type_record;

然后在包装中有类似的东西

vt type_table;
...
select type_record(x,y,z)
bulk collect into vt
from (...);

...
UDPATE tableX set.....
where ....
not EXISTs (select vt.column1 from table(vt) where ...)

并且一切正常。

但是我需要停止使用在数据库中声明的类型,因此我试图将这些类型转换为在包中声明的类型。

在包装定义中,我试图声明

TYPE type_record IS RECORD(
    column1        NUMBER,
    column2        NUMBER,
    column3        NUMBER);

TYPE type_table IS TABLE OF type_record;

然后在程序的程序包主体中,由于类型不同,我更改了代码

vt type_table;
...
select x,y,z
bulk collect into vt
from (...);

...
UDPATE tableX set.....
where ....
not EXISTs (select vt.column1 from table(vt) where ...)

现在我收到错误ORA-00902,它是由select from table(vt)中的not exists引起的。我检查了是否可以从表(vt)中选择*,而不是进行更新,是的,我可以在这种情况下使用它。

sql oracle plsql oracle12c
1个回答
0
投票

我想这是一个意见问题,因为我使用数据库级别类型,因为(imho)可以使代码保持干净。但这只是一种不同的观察方式。但是,至少在这种情况下,您要寻找的并不是那么困难。您已经在创建一个使用这些定义的程序包。您可以将定义移至包装规格中。这样,几乎不需要更改任何代码。同样,这些定义仍可以在包本身之外使用。

create or replace package pkg_t1 as  
   type type_record is record(
      column1        number,
      column2        number,
      column3        number);

   type type_table is table of type_record;

   function build_type_records(rows_to_build in integer) 
     return type_table;

   function build_pipe_records(rows_to_build in integer) 
     return type_table 
     pipelined;    

end pkg_t1;
/

create or replace package body pkg_t1 as

   function build_type_records(rows_to_build in integer) 
   return  type_table 
   is  
      v_type type_table := type_table();
   begin 
      for i in 1 .. rows_to_build 
      loop 
         v_type.extend;      
         v_type(i).column1 := trunc(dbms_random.value(1,100)); 
         v_type(i).column2 := trunc(dbms_random.value(100,500));
         v_type(i).column3 := dbms_random.value();
      end loop ;

     return  v_type;
   end build_type_records; 

  function build_pipe_records(rows_to_build in integer) 
    return type_table 
    pipelined 
  is
    v_rec type_table;
  begin
    v_rec:= build_type_records(rows_to_build); 
    for i in 1 .. v_rec.count
    loop
      pipe row (v_rec(i));
    end loop; 
  end build_pipe_records;

end pkg_t1;
/ 

declare 
  tt pkg_t1.type_table; 
  num_of_rows integer := &Number_of_rows;
begin
  tt := pkg_t1.build_type_records( num_of_rows );
  for i in 1 .. tt.count
  loop
      dbms_output.put_line( 'Result: '
                            || 'Column1==>' || tt(i).column1 || ', ' 
                            || 'Column2==>' || tt(i).column2 || ', '
                            || 'Column3==>' || tt(i).column3
                          ) ; 
  end loop; 
end ; 
/

select * from table(pkg_t1.build_pipe_records(&Rows_Desirded));
© www.soinside.com 2019 - 2024. All rights reserved.