删除oracle中从子查询返回的数据

时间:2018-02-02 09:34:21

标签: oracle

我有两张桌子。如果table1中的数据超过预定义的限制(比如说2),我需要将table1的剩余内容复制到table2,并从table1中删除相同的内容。

我使用以下查询将多余的数据从table1插入到table2。

 insert into table2 
  SELECT * FROM table1 WHERE ROWNUM < ((select count(*) from table1)-2);

现在我需要删除查询来从table1中删除上述内容。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

直接的方法是临时表中的临时存储。其内容可用于确定要从table1以及源到源表2中删除的数据。     假设(略微滥用表示法)为table1的PK列(或任何候选键的列) - 通常会有一些只包含1列的键。

create global temporary table t_interim as
   ( SELECT <pk> pkc FROM table1 WHERE ROWNUM < ((select count(*) from table1)-2 )
;

insert into table2 
   select * from table1 where <pk> IN (
    select pkc from t_interim
);

delete from table1 where <pk> IN (
    select pkc from t_interim
);

<强>替代

如果table1的任何键超过1列,请使用EXISTS子句,如下所示(表示table1中候选键的第i个组件):

create global temporary table t_interim as
   ( SELECT <ck_1> ck1, <ck_2> ck2, ..., <ck_n> ckn FROM table1 WHERE ROWNUM < ((select count(*) from table1)-2 )
;

insert into table2 
   select * from table1 t
    where exists (
             select 1
               from t_interim t_i
              where t.ck_1 = t_i.ck1
                and t.ck_2 = t_i.ck2
                    ...
                and t.ck_n = t_i.ckn
          )
        ;

delete from table1 t where
    where exists (
             select 1
               from t_interim t_i
              where t.ck_1 = t_i.ck1
                and t.ck_2 = t_i.ck2
                    ...
                and t.ck_n = t_i.ckn
          )
        ;

(从技术上讲,你可以尝试通过从任何CK的组件合成一个密钥来调整第一个方案,例如通过连接。你冒着引入歧义的风险((a bcab c) - &gt;(abcabc))或使用第一种方法进入实施限制(最大varchar长度))

注意 如果表没有PK,您可以使用table1的任何候选键来应用该技术。总会有一个,在极端情况下,它是所有列的集合。

这种情况可能是改进数据库设计并向table1(以及系统中缺少它的任何其他表)添加(合成)pk列的正确时机。