主要目标:我希望将小块的记录从“工作”表移动到存档。
准备:
create table working_tmp as select * from all_objects;
create table archive_tmp as select * from all_objects where 1=2;
安排:
首次尝试:
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? 我错过了什么吗?
答案 0 :(得分:0)
你的工作案例已经够好了。如果某人添加了一个列,则该语句将变为不可编译(如果描述为存储过程则无效),因此他将看到它并将对其进行编辑。
一般来说,“从工作人员转移到存档表”是一个值得怀疑的想法,首先你应该检查一下你是否真的需要它。通常情况下,它根本不需要或存在更便宜的方式。
执行此类移动的最简单方法是使用具有行移动选项的分区。您应该添加一个标志列 - 活动或存档的记录 - 在基于它的“活动”和“存档”分区时添加。当某人将记录标记为已存档时 - 它将自动移至存档分区。