sql - 如何同时插入两个表

标签 sql oracle

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

folder with columns folderid, foldername

link with columns linkid, url and folderid

我的目标表是:

new_folder with columns folderid, foldername

new_link with columns linkid, url and 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 更改,我就无法将链接映射到文件夹,除非我在一条语句中执行此操作(如果有意义的话)。

最佳答案

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

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;

您可能需要重组源子查询来创建一个列,该列指示每个文件夹名称的第一行,然后您可以在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 block 中而不是纯 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 解决方案已经可以处理这种情况。

关于sql - 如何同时插入两个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8169693/

相关文章:

oracle - 如何翻译或覆盖 Oracle APEX 中的标准文本字符串?

sql - 获得下一个约会

mysql - 使用 MySQL 在 SQL 中拆分字符串

mysql - 如何使用变量 SQL 获取总和

oracle - Oracle 存储过程的 varchar2 输入的默认大小是多少?可以更改吗?

oracle - 在Oracle中选择更高的时间戳精度有什么缺点?

mysql - 使用 DISTINCT 时发生了什么?

sql - 如何使用seek pagination获取下一个数据集?

sql - 哪些 SQL 查询操作可以根据顺序更改其值?

oracle - 从Oracle将数据导入Hive时Sqoop作业卡住了