使用返回的rowtype删除?

时间:2015-05-28 15:13:43

标签: sql oracle oracle11g

主要目标:我希望将小块的记录从“工作”表移动到存档。

准备:

create table working_tmp as select * from all_objects;
create table archive_tmp as select * from all_objects where 1=2;

安排:

  • 将working_tmp中的记录删除到集合中。
  • 将集合插入archive_tmp。

首次尝试:

declare
    type t_arr is table of working_tmp%rowtype;
    v_data t_arr;
begin
    delete from working_tmp 
    where owner = 'SYS'
    returning
      OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, 
      DATA_OBJECT_ID, OBJECT_TYPE, CREATED, LAST_DDL_TIME, 
      TIMESTAMP, STATUS, TEMPORARY, GENERATED, 
      SECONDARY, NAMESPACE, EDITION_NAME
    bulk collect into v_data;

    forall i in v_data.first..v_data.last
        insert into archive_tmp values v_data(i);
end;

这是有效的,但我不喜欢大写的一部分..如果有人后来在表中添加了一个列怎么办?

第二次尝试:

declare
    type t_arr is table of working_tmp%rowtype;
    v_data t_arr;
begin
    delete from working_tmp v 
    where owner = 'SYS'
    returning v.* bulk collect into v_data;

    forall i in v_data.first..v_data.last
        insert into archive_tmp values v_data(i);
end;

这不起作用..语法不好。

让我们尝试动态:

declare
    type t_arr is table of working_tmp%rowtype;
    v_data t_arr;
    v_col_list varchar2(32000);
begin
    select listagg(column_name, ',') within group (order by column_id) 
    into v_col_list
    from user_tab_cols
    where table_name = 'WORKING_TMP';

    execute immediate
         'delete from working_tmp v where owner = ''SYS'' returning ' || v_col_list || ' returning :data'
    returning bulk collect into v_data';

    forall i in v_data.first..v_data.last
        insert into archive_tmp values v_data(i);
end;

这个给了我'PLS-00429:不支持的功能与RETURNING子句'

我可以选择,然后删除,然后插入。但有没有办法用2个语句来做,而不是3个?

是否可以从DELETE语句返回rowtype? 我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

你的工作案例已经够好了。如果某人添加了一个列,则该语句将变为不可编译(如果描述为存储过程则无效),因此他将看到它并将对其进行编辑。

一般来说,“从工作人员转移到存档表”是一个值得怀疑的想法,首先你应该检查一下你是否真的需要它。通常情况下,它根本不需要或存在更便宜的方式。

执行此类移动的最简单方法是使用具有行移动选项的分区。您应该添加一个标志列 - 活动或存档的记录 - 在基于它的“活动”和“存档”分区时添加。当某人将记录标记为已存档时 - 它将自动移至存档分区。