Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
某些列的Pl/SQL批量迁移_Sql_Oracle_Plsql - Fatal编程技术网

某些列的Pl/SQL批量迁移

某些列的Pl/SQL批量迁移,sql,oracle,plsql,Sql,Oracle,Plsql,我知道有很多批量插入脚本,因为我是pl/sql新手,所以我很困惑。 我有两个表TABLEA(id,name,sirname,age)TABLEB(id,age),我想将所有数据从TABLEB迁移到TABLEA 我发现了一个链接,其中“FORALL Insert”解释了如何执行该操作。但它假定两个表列类型相同。但在我的情况下,我将复制到表A上的一些列 由于TABLEB有3000万的记录,性能非常重要。 还有一件事我想说的是TABLEB是外部表,我的意思是它是从txt文件中创建的,将适当的列映射到表

我知道有很多批量插入脚本,因为我是pl/sql新手,所以我很困惑。 我有两个表TABLEA(id,name,sirname,age)TABLEB(id,age),我想将所有数据从TABLEB迁移到TABLEA

我发现了一个链接,其中“FORALL Insert”解释了如何执行该操作。但它假定两个表列类型相同。但在我的情况下,我将复制到表A上的一些列

由于TABLEB有3000万的记录,性能非常重要。 还有一件事我想说的是TABLEB是外部表,我的意思是它是从txt文件中创建的,将适当的列映射到表中

那么,可以做些什么来修改我的案例中的以下脚本呢

CREATE TABLE servers2 AS
SELECT *
FROM servers
WHERE 1=2;

DECLARE
 CURSOR s_cur IS
 SELECT *
 FROM servers;

 TYPE fetch_array IS TABLE OF s_cur%ROWTYPE;
 s_array fetch_array;
BEGIN
  OPEN s_cur;
  LOOP
    FETCH s_cur BULK COLLECT INTO s_array LIMIT 1000;

    FORALL i IN 1..s_array.COUNT
    INSERT INTO servers2 VALUES s_array(i);

    EXIT WHEN s_cur%NOTFOUND;
  END LOOP;
  CLOSE s_cur;
  COMMIT;
END;

可能最快的方法是使用带有APPEND提示的普通旧INSERT:

 INSERT /*+APPEND*/ INTO table_a(id,age)
  SELECT id, age
  FROM table_b;

不需要FORALL/BULK COLLECT等。

可能最快的方法是使用带有APPEND提示的普通旧插入:

 INSERT /*+APPEND*/ INTO table_a(id,age)
  SELECT id, age
  FROM table_b;


无需全部/批量收集等。

您不必更改外部表的任何内容。由于有3000万数据,您可能会将限制增加到100000。但这完全取决于您的数据库设计和流量。但是我更喜欢增加限制。

您不必为外部表更改任何内容。由于有3000万数据,您可能会将限制增加到100000。但这完全取决于您的数据库设计和流量。但是我更喜欢增加限制。

肯定是更好的方法。我有两个问题,第一个问题是我必须调整限制,因为我有3000万数据,第二个问题是如果表a不是空的,并且它与表b有违反主键约束的公共数据。在这种情况下是否有办法忽略元组。@mmc18#1否(30MB不是很多数据)#2超出此问题的范围(提示:请参阅)!如果只是忽略存在主键冲突的新行,而不是将表更新为新值,那么只需使用不存在的相关子查询或左联接即可,如果您重复地从tablea中添加和删除行,那么使用APPEND插入会在表中留下一些空块或部分空块。您可以通过不使用APPEND或在插入之前合并表,或通过将数据复制到其他位置并截断表,然后在一次插入中同时插入旧数据和新数据来解决此问题。肯定是更好的方法。我有两个问题,首先我必须调整限制,因为我有3000万数据,其次,如果表_a不是空的,并且它与表_b有公共数据,这违反了主键约束。在这种情况下是否有办法忽略元组。@mmc18#1否(30MB不是很多数据)#2超出此问题的范围(提示:请参阅)!如果只是忽略存在主键冲突的新行,而不是将表更新为新值,那么只需使用不存在的相关子查询或左联接即可,如果您重复地从tablea中添加和删除行,那么使用APPEND插入会在表中留下一些空块或部分空块。您可以通过不使用APPEND或在插入之前合并表,或者通过将数据复制到其他位置并截断表,然后在一次插入中同时插入旧数据和新数据来处理此问题。不,完全忘记限制和PL/SQL游标。这是SQL的工作。30万行是巨大的数据。执行单个插入可能需要时间,并导致快照太旧错误。我更喜欢PL/SQL块,恐怕我不同意这一切。3000万行应该是一个简单的SQL插入,这将比基于PL/SQL的方法更快、更高效。快照太旧的错误不太可能发生,特别是在外部表作为数据源和直接路径插入的情况下,因为查询几乎不需要从撤消数据重建块。在回答时,我无法记住外部表。谢谢你指出。不,完全忘记限制和PL/SQL游标。这是SQL的工作。30万行是巨大的数据。执行单个插入可能需要时间,并导致快照太旧错误。我更喜欢PL/SQL块,恐怕我不同意这一切。3000万行应该是一个简单的SQL插入,这将比基于PL/SQL的方法更快、更高效。快照太旧的错误不太可能发生,特别是在外部表作为数据源和直接路径插入的情况下,因为查询几乎不需要从撤消数据重建块。在回答时,我无法记住外部表。谢谢你指出这一点。