如何同时插入两个表

时间:2011-11-17 15:25:06

标签: sql oracle

我希望我能够正确解释这一点。我需要将数据插入两个DB表。此数据已存储在另外两个表中,但需要进行迁移。为了简化事情,我们可以说这是我的源表:

  

具有列folderid,foldername

的文件夹      

链接列linkid,url和folderid

我的目的地表是:

  

new_folder,其中包含列folderid,foldername

     

new_link with columns linkid,url和folderid

还有其他列,但它们并不重要。我的问题是,无论是谁设置原始数据库都使用java中的随机数生成器来创建文件夹和链接ID,这些数字是完全垃圾。它们需要用数据库中存在的序列生成的数字替换。

所以我需要的是一个声明,它具有如下内容:

insert into new_folder(folderid, foldername), new_link(linkid, url, folderid)
values (select seq_folder_id.nextval, foldername, seq_link_id.nextval, url, seq_folder_id.currval from folder, link where folder.folderid = link.folderid).

可能有多个与该文件夹关联的链接。文件夹表中有200k行,链接表中有10倍,所以我需要一些脚本来运行和拉出所有文件夹,并使用新序列作为ID创建新条目。这本身就没问题,但如果我这样做,那么一旦ID被更改,我就无法将链接映射到文件夹,除非我在一个声明中这样做,如果这是有道理的。

1 个答案:

答案 0 :(得分:5)

这是一个关于多表插入的好教程:

http://www.oracle-developer.net/display.php?id=209

基本结构是:

INSERT ALL|FIRST
   [WHEN condition THEN] INTO target [VALUES]
   [WHEN condition THEN] INTO target [VALUES]
   ...
   [ELSE] INTO target [VALUES]
SELECT ...
FROM   source_query;

您可能希望重新构建源子查询以创建一个列,该列指示每个foldername的第一行,然后您可以在when条件中使用每个文件夹只将一行插入文件夹表,然后将所有行链接表。您还必须重新设置如何生成ID,以便每个链接行具有相同的folderID。换句话说,你学习聚合函数的时间!

示例:查看此查询并查看它是否可以帮助您弄清楚(提示,folder_rank可以成为folder_id的基础,以及group_rank如何驱动when子句来找出文件夹插入)

select dense_rank() over (order by foldername) as folder_rank,
       rank() over (parition by foldername order  by url) as group_rank
     , foldername
     , seq_link_id.nextval
     , url 
from folder, link 
where folder.folderid = link.folderid

或者,看看在一块pl / sql而不是纯SQL中执行此操作:

declare
  l_new_folder_id new_folder.folder_id%type;
begin
   for folder_Rec in (select folder_id, foldername from folder)
   loop
      insert into new_folder (folder_id, folder_name) 
      values ( seq_folder_id.nextval, folder_Rec.folder_name) 
      returning folder_id into l_new_folder_id;

      for link_rec in (select url from link where folder_id = folder_rec.folder_id)
          insert into new_link (link_id, folder_id, url) 
          values (seq_link_id.nextval, l_new_folder_id, link_rec.url);
      end loop;
    end loop;
    commit;
end;

有几种方法可以为这只猫提供皮肤,而复杂的SQL可能不是初学者的最佳选择。另外,检查源数据 - 如果您有没有任何链接的文件夹,那么如果您希望插入无链接文件夹,那么纯SQL方法也必须包含外连接而不是当前定义。 PL / Sql解决方案已经处理了这种情况。