我希望我能够正确解释这一点。我需要将数据插入两个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被更改,我就无法将链接映射到文件夹,除非我在一个声明中这样做,如果这是有道理的。
答案 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解决方案已经处理了这种情况。