【问题标题】:delete with returning rowtype?删除并返回行类型?
【发布时间】:2015-05-28 15:13:43
【问题描述】:

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

准备:

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 语句返回行类型? 我错过了什么吗?

【问题讨论】:

  • 我在 12c SE 也有类似的机会。就我而言,我想更改主键中的一列。我正在删除旧记录,然后在更改的列中重新合并。这是同样的问题。我试过RETURNING ROW 而不是RETURNING v.*,没有运气。这种事情能做到吗?
  • 您可以在不移动任何数据的情况下重命名或更改列的数据类型。如果您需要详细信息或问题更复杂 - 创建一个问题。

标签: sql oracle oracle11g


【解决方案1】:

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

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

进行这种移动的最简单方法是使用带有行移动选项的分区。您应该添加一个标志列 - 记录是活动的还是归档的 - 基于它创建一个“活动”和“归档”分区。当有人将记录标记为已归档时-它将自动移动到归档分区。

【讨论】:

  • 你是对的,第一次尝试会“快速失败”(没想到这一点)。但是,如果我可以实现零维护,那就更好了。
猜你喜欢
  • 2017-02-25
  • 2019-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 2017-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多