2013-08-30 47 views
0

我知道有很多批量插入脚本,因为我是新来的pl/sql我很困惑。 我有两个表TABLEA(ID,名称,SIRNAME,年龄)TABLEB(ID,年龄),我想从TABLEB迁移到TABLEA的所有数据。某些列的Pl/SQL批量迁移

我找到了一个链接http://psoug.org/reference/array_processing.html其中“FORALL插入”说明了如何做到这一点。但是它假定两个表格列类型是相同的。但在我的情况下,我会复制到TABLEA的一些列。

由于TABLEB有30万条记录,性能很重要。 还有一件事我想说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; 

回答

4

可能是最快的方法是使用一个普通的老INSERT与APPEND提示:

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

无需FORALL/BULK COLLECT等

+3

绝对是更好的方法。 –

+0

我有两个问题,首先我必须调整极限,因为我有30M数据,其次如果table_a不是空的,并且它有与table_b共同的数据违反主键约束。在这种情况下,有没有办法忽略斑点。 –

+1

@ mmc18#1否(30MB不是太多数据)。 #2超出了这个问题的范围(提示:参见[合并](http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_9016.htm#SQLRF01606))! – user272735

0

你不要有任何改变的外部桌子。您可以将限制增加到100000,因为您拥有30M数据。但它完全取决于你的数据库设计和你有多少流量。但我更喜欢增加限制。

+0

不,请完全忘记限制和PL/SQL游标。这是SQL的一项工作。 –

+0

3000万行是巨大的数据。执行单个插入可能需要时间并导致快照太旧的错误。我更喜欢PL/SQL块。 –

+2

恐怕我不同意这一切。 3000万行应该是一个简单的单个SQL插入,这比PL/SQL方法更快,更高效。快照太旧的错误是不太可能的,尤其是在将外部表作为数据源和直接路径插入的情况下,因为查询很少需要从UNDO数据重建块。 –