如何将rowid组合成与表相同的行类型的集合?

时间:2016-12-04 13:48:11

标签: oracle plsql

  

背景

     

来自Nicholas Krasnov和krokodilko在问题中的回答   How can I create a collection of the same type as a record in a table?,   我发现您可以使用%ROWTYPE属性来创建集合   与表格相同的类型。

     

但是,我还需要捕获表中的ROWID   集合,因为我将用它来删除那些行。

  

问题

     

如何将ROWID组合成与a相同的行类型的集合   表

  

我已尝试过的内容

     

我创建了一个嵌套类型,其原始类型相同   rowtype,包含rowid的附加字段。   代码示例如下:

create or replace procedure p_test as
l_cur_limit pls_integer := 500;

type rec_with_rowid is record
(
    t1 mytable%rowtype,
    row_id rowid
);

type tab_to_be_moved is table of rec_with_rowid;

l_to_be_moved tab_to_be_moved;

cursor c_get_to_be_moved is
select mytable.*, mytable.rowid
from mytable;

begin  

open c_get_to_be_moved;
loop
    fetch c_get_to_be_moved
    bulk collect into l_to_be_moved limit l_cur_limit; --Fails here, as the collection
                                                       --is not of the same type
    exit when l_to_be_moved.count = 0;      

    for i in 1.. l_to_be_moved.count loop
        begin
            insert into mytable@remotedb values l_to_be_moved(i);
        exception
            when others then
                dbms_output.put_line(sqlerrm);
                l_to_be_moved.delete(i);
        end;    
    end loop;
--        forall i in 1.. l_to_be_moved.count
-- Need rowid to delete, as the audit tables don't have PK for performance reasons
    commit;
end loop;          
close c_get_to_be_moved;

exception
    when others then
        dbms_output.put_line(sqlerrm);

end;

/

2 个答案:

答案 0 :(得分:2)

您至少有两个选择。

1)声明一个游标和cursor_name%rowtype元素的集合;

create table foo( c1 number, c2 varchar2(11));


declare
  cursor c1 is
    select f.*
        , rowid as rid
      from foo f;
  type t_col is table of c1%rowtype;
  l_col t_col;
begin
  open c1;
  fetch c1 bulk collect into l_col;
  /*  further processing */  
end;

2)创建一个包含rowid的视图,然后声明一个元素为view_name%row_type的集合,或声明一个从该视图中选择的游标,因为您要获取并处理特定数量的行一时间:

create or replace view v_foo as
  select f.*
      , rowid as rid
    from foo f;

declare
  type t_col is table of v_foo%rowtype;
  l_col t_col;
begin
 -- or declare a cursor
  select *
    bulk collect into l_col
    from v_foo;
  /*  further processing */  
end;

答案 1 :(得分:1)

您将第一个类型定义为,而应将其定义为第二个类型。我会做以下(只需要一个类型定义):

type tab_with_rowid is record
(
    t1       mytable%rowtype,
    row_id   rowid
);

我的错误

一旦有了这种类型,就需要为TABLE定义一个类似于:

的类型
type tab_with_rowid_T is table of tab_with_rowid ;

然后定义一个变量:

tab_with_rowid_V tab_with_rowid_T ;

现在,您可以使用此变量来接收光标的内容。

希望这里不再犯错误。