oracle批量删除:从表中删除数组中的列

时间:2015-01-13 07:37:57

标签: oracle plsql

我正在尝试收集一系列修订版数字。
我将用于删除多个审计表中的记录 所以我编写了一个plsql来收集该数组,并根据使用该数组的条件在其他表上运行delete

declare 
  type NumberArray is table of number index by binary_integer;
  revisions NumberArray;
Begin
  select rev bulk collect into revisions from (
    select t.rev, row_number() over (partition by 
        column1,
        column2
        order by column3) rn
    from table1 t)
  where rn <> 1;

  dbms_output.put_line(revisions.count || ' records found from table2 to be deleted');
  delete from table2 where rev in (revisions);
  dbms_output.put_line('deleted from table2');

我正在

 PLS-00382: expression is of wrong type
 06550. 00000 -  "line %s, column %s:\n%s"
 *Cause:    Usually a PL/SQL compilation error.

rev的数据类型是table1中的数字。

3 个答案:

答案 0 :(得分:6)

这是FORALL陈述

的合适人选
declare 
  type NumberArray is table of number(10) index by binary_integer;
  revisions NumberArray;
Begin
  select rev bulk collect into revisions from (
    select t.rev, row_number() over (partition by 
        column1,
        column2
        order by column3) rn
    from table1 t)
  where rn <> 1;

  dbms_output.put_line(revisions.count || ' records found from table2 to be deleted');
  forall i in revisions.first .. revisions.last
       delete from table2 where rev = revisions(i);
  dbms_output.put_line('deleted from table2');
End;

但是如果你仍然坚持使用IN条件,你必须在架构级别定义你的类型:

create type NumberArray as table of number;

然后像这样使用它

declare 
  revisions NumberArray;
Begin
  select rev bulk collect into revisions from (
    select t.rev, row_number() over (partition by 
        column1,
        column2
        order by column3) rn
    from table1 t)
  where rn <> 1;

  dbms_output.put_line(revisions.count || ' records found from table2 to be deleted');
  delete from table2 where rev in (select column_value from table(revisions));
  dbms_output.put_line('deleted from table2');
End;

答案 1 :(得分:3)

一定是这个:

delete from table2 where rev MEMBER OF revisions;

or 

delete from table2 where rev =ANY (SELECT COLUMN_VALUE FROM TABLE(revisions));

or 

forall i in revisions.FIRST..revisions.LAST
delete from table2 where rev = revisions(i);

or 

delete from table2 where rev =ANY (
select rev 
from (
    select t.rev, row_number() over (partition by 
        column1,
        column2
        order by column3) rn
    from table1 t)
  where rn <> 1
);

or (not the preferred way of doing it)

for i in revisions.FIRST..revisions.LAST LOOP
   delete from table2 where rev = revisions(i);
END LOOP;

正如Marcin Wroblewski所写,必须在Schema级别创建嵌套表。

答案 2 :(得分:1)

如果可以在纯 SQL 中完成,为什么要在 PL / SQL 中执行此操作?您不必要在两个引擎之间引入上下文切换

所有PL / SQL代码都只是一个简单的 DELETE语句 -

DELETE FROM table2 WHERE rev IN(
   SELECT rev FROM(
      select t.rev, row_number() over (partition by 
              column1,
              column2
              order by column3) rn
      from table1 t)
  where rn <> 1
);